Re: Bug in the kernel ?

Benjamin C R LaHaise (blah@dot.superaje.com)
Wed, 20 Nov 1996 15:36:15 -0500 (EST)


On Sun, 20 Oct 1996, Dietmar Kling wrote:
...
> I am still using a 2.0.20 Kernel and i can freeze it with the following
> sequence on the terminal (not using X-Windows).
>
> cp -R /dos/d/somedirectory /usr/local/
> ^^^^ ^^^^
> ide-drive scsi-drive
> vfat ext2
... rest of problem description deleted

I think this is the same bug I found earlier with msdos/samba. Could you
try the following patch? It is against 2.0.25, but should mesh cleanly
with .20.

-b
===snip===
Index: linux/Documentation/filesystems/00-INDEX
diff -u linux/Documentation/filesystems/00-INDEX:1.1.1.1 linux/Documentation/filesystems/00-INDEX:1.2
--- linux/Documentation/filesystems/00-INDEX:1.1.1.1 Wed Nov 6 23:11:36 1996
+++ linux/Documentation/filesystems/00-INDEX Thu Nov 7 19:01:06 1996
@@ -14,3 +14,5 @@
- info on the umsdos extensions to the msdos filesystem.
vfat.txt
- info on using the VFAT filesystem used in Win NT and Win 95
+vfs.txt
+ - info on the kernel's VFS layer in general
Index: linux/Documentation/filesystems/vfs.txt
diff -u /dev/null linux/Documentation/filesystems/vfs.txt:1.1
--- /dev/null Thu Nov 7 20:23:15 1996
+++ linux/Documentation/filesystems/vfs.txt Thu Nov 7 19:01:06 1996
@@ -0,0 +1,173 @@
+A Brief Overview of the Virtual File System
+===========================================
+ by Benjamin LaHaise (blah@dot.superaje.com)
+
+Noone else seems to be writing this, so here's a quick description of what
+I've learned while writing lofs...
+
+The VFS relatively simple, but it is nice not to have to browse through
+pages of code to determine what is expected when writing a filesystem.
+Hopefully this helps anyone attempting such a feat, as well as clearing up
+a few important points/dependancies.
+
+
+register_filesystem (struct file_system_type *fstype)
+=====================================================
+
+All filesystems are created equal... or at least they start out that way.
+A filesystem, be it in module form, or linked into the kernel, needs to add
+itself to the table of filesystems by calling register_filesystem with an
+initialized file_system_type structure. Any further functions of the
+filesystem are accessed through the following function tables...
+
+
+struct file_system_type
+=======================
+
+ struct super_block *(*read_super) (struct super_block *sb, void *options, int silent);
+
+ This is the entry point of all filesystems. If the filesystem succeeds
+ in mounting itself, sb should be returned, otherwise NULL. options is
+ a pointer to a maximum of PAGE_SIZE-1 bytes of options, typically a zero
+ terminated string passed from mount. This page is freed after read_super
+ returns, so do not use any pointers into it.
+
+ This routine _must_ set the s_op member of sb to point to a valid
+ super_operations structure.
+
+ const char *name;
+
+ Name points to a string that the system will know the filesystem by.
+
+ int requires_dev;
+
+ Set this flag to 1 if the filesystem requires a block device to be mounted
+ on.
+
+ struct file_system_type * next;
+
+ This field points to the next file_system_type that is present in the system,
+ and should be initialized to NULL.
+
+struct super_operations
+=======================
+
+The super_operations structure is found through the s_op member of the
+super_block structure.
+
+ void (*read_inode) (struct inode *inode);
+ [optional - doesn't quite make sense]
+ read_inode is called by the VFS when iget is called requesting an inode
+ not already present in the inode table. i_ino is set to the number of the
+ inode requested.
+
+ The i_op member of inode should be set to a valid inode_operations
+ structure. Typically filesystems have separate inode_operations for
+ directories, files and symlinks. i_op can be NULL.
+
+ int (*notify_change) (struct inode *, struct iattr *);
+ [optional]
+ void (*write_inode) (struct inode *);
+ [optional]
+
+ int (*put_inode) (struct inode *inode);
+ [optional]
+ put_inode is called by the VFS when the last instance of inode is released
+ with a call to iput. The only special consideration that should be made
+ is that iget may reuse inode without calling read_inode unless clear_inode
+ is called. put_inode MUST return 1 if it called clear_inode on the inode,
+ otherwise zero.
+
+ void (*put_super) (struct super_block *);
+ [optional]
+ void (*write_super) (struct super_block *);
+ [optional]
+ void (*statfs) (struct super_block *, struct statfs *, int);
+ [optional]
+ int (*remount_fs) (struct super_block *, int *, char *);
+ [optional]
+
+
+struct inode_operations
+=======================
+
+ struct file_operations * default_file_ops;
+ [mandatory]
+ All inode_operations structures must have default_file_ops pointing to
+ a valid file_operations structure.
+
+ int (*create) (struct inode *,const char *,int,int,struct inode **);
+ [optional]
+
+ int (*lookup) (struct inode *dir, const char *name, int len, struct inode **result);
+ [optional]
+ lookup is called when the VFS wishes to have the filesystem resolve a name
+ into an inode. Dir is a directory on the filesystem that [hopefully] contains
+ the zero terminated string name (length len). A return value of zero indicates
+ that there is a valid inode stored in *result.
+
+*** Note: lofs assumes that any filesystem returns an inode within the filesystem
+ for all directory inodes. Therefore, __iget(sb,ino,0) should be used to fetch
+ the inode in a filesystem's lookup routine.
+
+ int (*link) (struct inode *,struct inode *,const char *,int);
+ [optional]
+ int (*unlink) (struct inode *,const char *,int);
+ [optional]
+ int (*symlink) (struct inode *,const char *,int,const char *);
+ [optional]
+ int (*mkdir) (struct inode *,const char *,int,int);
+ [optional]
+ int (*rmdir) (struct inode *,const char *,int);
+ [optional]
+ int (*mknod) (struct inode *,const char *,int,int,int);
+ [optional]
+ int (*rename) (struct inode *,const char *,int,struct inode *,const char *,int, int);
+ [optional]
+
+ int (*readlink) (struct inode *inode, char *buf, int len);
+ [optional]
+ readlink is called by the VFS to read the contents of a symbolic link.
+ inode is an inode that meets the S_ISLNK test, and buf points to a buffer
+ of len bytes.
+
+ int (*follow_link) (struct inode *,struct inode *,int,int,struct inode **);
+ [optional]
+ The follow_link function is only nescessary if a filesystem uses a really
+ twisted form of symbolic links - namely if the symbolic link comes from a
+ foriegn filesystem that makes no sense....
+ I threw this one out - too much redundant code!
+
+ int (*readpage) (struct inode *, struct page *); [optional]
+ int (*writepage) (struct inode *, struct page *); [mandatory with readpage]
+
+ In order for files to be mmap'd, readpage and writepage are required.
+ A filesystem can use generic_readpage/writepage if it supports the bmap
+ function. Otherwise, a custom version must be written.
+
+ int (*bmap) (struct inode *,int);
+ [optional]
+ void (*truncate) (struct inode *);
+ [optional]
+ int (*permission) (struct inode *, int);
+ [optional]
+ int (*smap) (struct inode *,int);
+ [optional]
+
+struct file_operations
+======================
+
+ int (*lseek) (struct inode *, struct file *, off_t, int);
+ int (*read) (struct inode *, struct file *, char *, int);
+ int (*write) (struct inode *, struct file *, const char *, int);
+ int (*readdir) (struct inode *, struct file *, void *, filldir_t);
+ int (*select) (struct inode *, struct file *, int, select_table *);
+ int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
+ int (*mmap) (struct inode *, struct file *, struct vm_area_struct *);
+ int (*open) (struct inode *, struct file *);
+ void (*release) (struct inode *, struct file *);
+ int (*fsync) (struct inode *, struct file *);
+ int (*fasync) (struct inode *, struct file *, int);
+ int (*check_media_change) (kdev_t dev);
+ int (*revalidate) (kdev_t dev);
+
Index: linux/fs/exec.c
diff -u linux/fs/exec.c:1.1.1.1 linux/fs/exec.c:1.2
--- linux/fs/exec.c:1.1.1.1 Wed Nov 6 23:10:12 1996
+++ linux/fs/exec.c Thu Nov 7 00:03:40 1996
@@ -131,16 +131,17 @@
f->f_pos = 0;
f->f_reada = 0;
f->f_op = inode->i_op->default_file_ops;
+ inode->i_count++;
if (f->f_op->open) {
int error = f->f_op->open(inode,f);
if (error) {
f->f_count--;
put_unused_fd(fd);
+ iput(inode);
return error;
}
}
current->files->fd[fd] = f;
- inode->i_count++;
}
return fd;
}
Index: linux/fs/inode.c
diff -u linux/fs/inode.c:1.1.1.1 linux/fs/inode.c:1.2
--- linux/fs/inode.c:1.1.1.1 Wed Nov 6 23:10:12 1996
+++ linux/fs/inode.c Thu Nov 7 00:03:40 1996
@@ -420,7 +420,7 @@
return;
wait_on_inode(inode);
if (!inode->i_count) {
- printk("VFS: iput: trying to free free inode\n");
+ printk("VFS: iput: trying to free free inode (%08lx)\n", ((long *)&inode)[-1]);
printk("VFS: device %s, inode %lu, mode=0%07o\n",
kdevname(inode->i_rdev), inode->i_ino, inode->i_mode);
return;
@@ -441,8 +441,7 @@
}

if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->put_inode) {
- inode->i_sb->s_op->put_inode(inode);
- if (!inode->i_nlink)
+ if (inode->i_sb->s_op->put_inode(inode))
return;
}

Index: linux/fs/namei.c
diff -u linux/fs/namei.c:1.1.1.1 linux/fs/namei.c:1.3
--- linux/fs/namei.c:1.1.1.1 Wed Nov 6 23:10:12 1996
+++ linux/fs/namei.c Thu Nov 7 16:31:51 1996
@@ -157,7 +157,7 @@
struct inode ** result)
{
struct super_block * sb;
- int perm;
+ int perm, err = 0;

*result = NULL;
if (!dir)
@@ -169,11 +169,12 @@
*result = dir;
return 0;
} else if ((sb = dir->i_sb) && (dir == sb->s_mounted)) {
+ if (sb->s_covered)
+ sb->s_covered->i_count++; /* avoid the race */
iput(dir);
dir = sb->s_covered;
if (!dir)
return -ENOENT;
- dir->i_count++;
}
}
if (!dir->i_op || !dir->i_op->lookup) {
@@ -188,9 +189,24 @@
*result = dir;
return 0;
}
- return dir->i_op->lookup(dir, name, len, result);
+ if (!(err = dir->i_op->lookup(dir, name, len, result))) {
+ while ((*result)->i_mount) {
+ struct inode *tmp = (*result)->i_mount;
+ tmp->i_count++;
+ iput(*result);
+ *result = tmp;
+ }
+ }
+ return err;
}

+/*
+ * Couldn't follow_link be implemented using read_link? It would save the
+ * cost of having horribly redundant code in all of the lower filesystem
+ * layers, as well as letting us add such future features as environment
+ * variable expansion through symlinks since the resolve routine would be
+ * centralized. Just a thought. --blah
+ */
int follow_link(struct inode * dir, struct inode * inode,
int flag, int mode, struct inode ** res_inode)
{
@@ -259,8 +275,7 @@
return 0;
}

-static int _namei(const char * pathname, struct inode * base,
- int follow_links, struct inode ** res_inode)
+int _namei(const char * pathname, struct inode * base, int follow_links, struct inode ** res_inode)
{
const char *basename;
int namelen,error;
Index: linux/fs/open.c
diff -u linux/fs/open.c:1.1.1.1 linux/fs/open.c:1.2
--- linux/fs/open.c:1.1.1.1 Wed Nov 6 23:10:12 1996
+++ linux/fs/open.c Thu Nov 7 00:03:41 1996
@@ -267,7 +267,7 @@

asmlinkage int sys_chdir(const char * filename)
{
- struct inode * inode;
+ struct inode * inode, *tmp;
int error;

error = namei(filename,&inode);
@@ -281,14 +281,15 @@
iput(inode);
return error;
}
- iput(current->fs->pwd);
+ tmp = current->fs->pwd;
current->fs->pwd = inode;
+ iput(tmp);
return (0);
}

asmlinkage int sys_fchdir(unsigned int fd)
{
- struct inode * inode;
+ struct inode * inode, *tmp;
struct file * file;
int error;

@@ -300,9 +301,10 @@
return -ENOTDIR;
if ((error = permission(inode,MAY_EXEC)) != 0)
return error;
- iput(current->fs->pwd);
+ tmp = current->fs->pwd;
current->fs->pwd = inode;
inode->i_count++;
+ iput(tmp);
return (0);
}

Index: linux/fs/affs/inode.c
diff -u linux/fs/affs/inode.c:1.1.1.1 linux/fs/affs/inode.c:1.2
--- linux/fs/affs/inode.c:1.1.1.1 Wed Nov 6 23:10:19 1996
+++ linux/fs/affs/inode.c Thu Nov 7 00:03:52 1996
@@ -829,18 +829,19 @@
return 0;
}

-void
+int
affs_put_inode(struct inode *inode)
{
pr_debug("AFFS: put_inode(ino=%lu, nlink=%u)\n",inode->i_ino,inode->i_nlink);
if (inode->i_nlink) {
- return;
+ return 0;
}
inode->i_size = 0;
if (S_ISREG(inode->i_mode) && !inode->u.affs_i.i_hlink)
affs_truncate(inode);
affs_free_block(inode->i_sb,inode->i_ino);
clear_inode(inode);
+ return 1;
}

struct inode *
Index: linux/fs/affs/namei.c
diff -u linux/fs/affs/namei.c:1.1.1.1 linux/fs/affs/namei.c:1.2
--- linux/fs/affs/namei.c:1.1.1.1 Wed Nov 6 23:10:19 1996
+++ linux/fs/affs/namei.c Thu Nov 7 00:03:53 1996
@@ -160,7 +160,7 @@
if (FILE_END(bh->b_data,dir)->original)
ino = htonl(FILE_END(bh->b_data,dir)->original);
affs_brelse(bh);
- if ((*result = iget(dir->i_sb,ino)))
+ if ((*result = __iget(dir->i_sb,ino, 0)))
res = 0;
else
res = -EACCES;
Index: linux/fs/ext/freelists.c
diff -u linux/fs/ext/freelists.c:1.1.1.1 linux/fs/ext/freelists.c:1.2
--- linux/fs/ext/freelists.c:1.1.1.1 Wed Nov 6 23:10:13 1996
+++ linux/fs/ext/freelists.c Thu Nov 7 00:03:56 1996
@@ -172,7 +172,7 @@
#endif
}

-void ext_free_inode(struct inode * inode)
+int ext_free_inode(struct inode * inode)
{
struct buffer_head * bh;
struct ext_free_inode * efi;
@@ -182,22 +182,22 @@
kdev_t dev;

if (!inode)
- return;
+ return 0;
if (!inode->i_dev) {
printk("free_inode: inode has no device\n");
- return;
+ return 0;
}
if (inode->i_count != 1) {
printk("free_inode: inode has count=%d\n",inode->i_count);
- return;
+ return 0;
}
if (inode->i_nlink) {
printk("free_inode: inode has nlink=%d\n",inode->i_nlink);
- return;
+ return 0;
}
if (!inode->i_sb) {
printk("free_inode: inode on non-existent device\n");
- return;
+ return 0;
}
sb = inode->i_sb;
ino = inode->i_ino;
@@ -207,7 +207,7 @@
if (ino < 1 || ino > sb->u.ext_sb.s_ninodes) {
printk("free_inode: inode 0 or non-existent inode\n");
unlock_super (sb);
- return;
+ return 1;
}
if (sb->u.ext_sb.s_firstfreeinodeblock)
efi = ((struct ext_free_inode *) sb->u.ext_sb.s_firstfreeinodeblock->b_data) +
@@ -234,6 +234,7 @@
sb->s_dirt = 1;
mark_buffer_dirty(sb->u.ext_sb.s_firstfreeinodeblock, 1);
unlock_super (sb);
+ return 1;
}

struct inode * ext_new_inode(const struct inode * dir)
Index: linux/fs/ext/inode.c
diff -u linux/fs/ext/inode.c:1.1.1.1 linux/fs/ext/inode.c:1.2
--- linux/fs/ext/inode.c:1.1.1.1 Wed Nov 6 23:10:13 1996
+++ linux/fs/ext/inode.c Thu Nov 7 00:03:56 1996
@@ -23,13 +23,13 @@
#include <asm/system.h>
#include <asm/segment.h>

-void ext_put_inode(struct inode *inode)
+int ext_put_inode(struct inode *inode)
{
if (inode->i_nlink)
- return;
+ return 0;
inode->i_size = 0;
ext_truncate(inode);
- ext_free_inode(inode);
+ return ext_free_inode(inode);
}

void ext_put_super(struct super_block *sb)
Index: linux/fs/ext/namei.c
diff -u linux/fs/ext/namei.c:1.1.1.1 linux/fs/ext/namei.c:1.2
--- linux/fs/ext/namei.c:1.1.1.1 Wed Nov 6 23:10:13 1996
+++ linux/fs/ext/namei.c Thu Nov 7 00:03:56 1996
@@ -168,7 +168,7 @@
}
ino = de->inode;
brelse(bh);
- if (!(*result = iget(dir->i_sb,ino))) {
+ if (!(*result = __iget(dir->i_sb,ino,0))) {
iput(dir);
return -EACCES;
}
Index: linux/fs/ext2/ialloc.c
diff -u linux/fs/ext2/ialloc.c:1.1.1.1 linux/fs/ext2/ialloc.c:1.2
--- linux/fs/ext2/ialloc.c:1.1.1.1 Wed Nov 6 23:10:16 1996
+++ linux/fs/ext2/ialloc.c Thu Nov 7 00:03:59 1996
@@ -151,7 +151,7 @@
return 0;
}

-void ext2_free_inode (struct inode * inode)
+int ext2_free_inode (struct inode * inode)
{
struct super_block * sb;
struct buffer_head * bh;
@@ -163,24 +163,24 @@
struct ext2_super_block * es;

if (!inode)
- return;
+ return 0;
if (!inode->i_dev) {
printk ("ext2_free_inode: inode has no device\n");
- return;
+ return 0;
}
if (inode->i_count > 1) {
printk ("ext2_free_inode: inode has count=%d\n",
inode->i_count);
- return;
+ return 0;
}
if (inode->i_nlink) {
printk ("ext2_free_inode: inode has nlink=%d\n",
inode->i_nlink);
- return;
+ return 0;
}
if (!inode->i_sb) {
printk("ext2_free_inode: inode on nonexistent device\n");
- return;
+ return 0;
}

ext2_debug ("freeing inode %lu\n", inode->i_ino);
@@ -192,7 +192,7 @@
ext2_error (sb, "free_inode",
"reserved inode or nonexistent inode");
unlock_super (sb);
- return;
+ return 0;
}
es = sb->u.ext2_sb.s_es;
block_group = (inode->i_ino - 1) / EXT2_INODES_PER_GROUP(sb);
@@ -222,6 +222,7 @@
sb->s_dirt = 1;
clear_inode (inode);
unlock_super (sb);
+ return 1;
}

/*
Index: linux/fs/ext2/inode.c
diff -u linux/fs/ext2/inode.c:1.1.1.1 linux/fs/ext2/inode.c:1.2
--- linux/fs/ext2/inode.c:1.1.1.1 Wed Nov 6 23:10:16 1996
+++ linux/fs/ext2/inode.c Thu Nov 7 00:03:59 1996
@@ -29,19 +29,19 @@

static int ext2_update_inode(struct inode * inode, int do_sync);

-void ext2_put_inode (struct inode * inode)
+int ext2_put_inode (struct inode * inode)
{
ext2_discard_prealloc (inode);
if (inode->i_nlink || inode->i_ino == EXT2_ACL_IDX_INO ||
inode->i_ino == EXT2_ACL_DATA_INO)
- return;
+ return 0;
inode->u.ext2_i.i_dtime = CURRENT_TIME;
inode->i_dirt = 1;
ext2_update_inode(inode, IS_SYNC(inode));
inode->i_size = 0;
if (inode->i_blocks)
ext2_truncate (inode);
- ext2_free_inode (inode);
+ return ext2_free_inode (inode);
}

#define inode_bmap(inode, nr) ((inode)->u.ext2_i.i_data[(nr)])
Index: linux/fs/ext2/namei.c
diff -u linux/fs/ext2/namei.c:1.1.1.1 linux/fs/ext2/namei.c:1.2
--- linux/fs/ext2/namei.c:1.1.1.1 Wed Nov 6 23:10:16 1996
+++ linux/fs/ext2/namei.c Thu Nov 7 00:04:00 1996
@@ -174,7 +174,7 @@
iput(dir);
return -ENOENT;
}
- if (!(*result = iget (dir->i_sb, ino))) {
+ if (!(*result = __iget (dir->i_sb, ino, 0))) { /* don't cross mnt points */
iput (dir);
return -EACCES;
}
@@ -191,7 +191,7 @@
ino = de->inode;
dcache_add(dir, name, len, ino);
brelse (bh);
- if (!(*result = iget (dir->i_sb, ino))) {
+ if (!(*result = __iget (dir->i_sb, ino, 0))) { /* don't cross mnt points */
iput (dir);
return -EACCES;
}
Index: linux/fs/fat/inode.c
diff -u linux/fs/fat/inode.c:1.1.1.1 linux/fs/fat/inode.c:1.2
--- linux/fs/fat/inode.c:1.1.1.1 Wed Nov 6 23:10:20 1996
+++ linux/fs/fat/inode.c Thu Nov 7 00:04:02 1996
@@ -27,7 +27,7 @@



-void fat_put_inode(struct inode *inode)
+int fat_put_inode(struct inode *inode)
{
struct inode *depend, *linked;
struct super_block *sb;
@@ -44,7 +44,7 @@
MSDOS_I(inode)->i_linked = NULL;
}
if (MSDOS_I(inode)->i_busy) fat_cache_inval_inode(inode);
- return;
+ return 0;
}
inode->i_size = 0;
fat_truncate(inode);
@@ -54,7 +54,7 @@
printk("Invalid link (0x%p): expected 0x%p, got 0x%p\n",
depend, inode, MSDOS_I(depend)->i_old);
fat_fs_panic(sb,"...");
- return;
+ return 1;
}
MSDOS_I(depend)->i_old = NULL;
iput(depend);
@@ -64,11 +64,12 @@
printk("Invalid link (0x%p): expected 0x%p, got 0x%p\n",
linked, inode, MSDOS_I(linked)->i_oldlink);
fat_fs_panic(sb,"...");
- return;
+ return 1;
}
MSDOS_I(linked)->i_oldlink = NULL;
iput(linked);
}
+ return 1;
}


Index: linux/fs/hpfs/hpfs_fs.c
diff -u linux/fs/hpfs/hpfs_fs.c:1.1.1.1 linux/fs/hpfs/hpfs_fs.c:1.2
--- linux/fs/hpfs/hpfs_fs.c:1.1.1.1 Wed Nov 6 23:10:18 1996
+++ linux/fs/hpfs/hpfs_fs.c Thu Nov 7 00:04:06 1996
@@ -1166,7 +1166,7 @@
* Go find or make an inode.
*/

- if (!(inode = iget(dir->i_sb, ino)))
+ if (!(inode = __iget(dir->i_sb, ino, 0)))
goto bail1;

/*
Index: linux/fs/isofs/namei.c
diff -u linux/fs/isofs/namei.c:1.1.1.1 linux/fs/isofs/namei.c:1.2
--- linux/fs/isofs/namei.c:1.1.1.1 Wed Nov 6 23:10:14 1996
+++ linux/fs/isofs/namei.c Thu Nov 7 00:04:08 1996
@@ -268,7 +268,7 @@
brelse(bh);
}

- if (!(*result = iget(dir->i_sb,ino))) {
+ if (!(*result = __iget(dir->i_sb,ino,0))) {
iput(dir);
return -EACCES;
}
Index: linux/fs/minix/bitmap.c
diff -u linux/fs/minix/bitmap.c:1.1.1.1 linux/fs/minix/bitmap.c:1.2
--- linux/fs/minix/bitmap.c:1.1.1.1 Wed Nov 6 23:10:14 1996
+++ linux/fs/minix/bitmap.c Thu Nov 7 00:04:11 1996
@@ -175,43 +175,44 @@
brelse (bh);
}

-void minix_free_inode(struct inode * inode)
+int minix_free_inode(struct inode * inode)
{
struct buffer_head * bh;
unsigned long ino;

if (!inode)
- return;
+ return 0;
if (!inode->i_dev) {
printk("free_inode: inode has no device\n");
- return;
+ return 0;
}
if (inode->i_count != 1) {
printk("free_inode: inode has count=%d\n",inode->i_count);
- return;
+ return 0;
}
if (inode->i_nlink) {
printk("free_inode: inode has nlink=%d\n",inode->i_nlink);
- return;
+ return 0;
}
if (!inode->i_sb) {
printk("free_inode: inode on nonexistent device\n");
- return;
+ return 0;
}
if (inode->i_ino < 1 || inode->i_ino >= inode->i_sb->u.minix_sb.s_ninodes) {
printk("free_inode: inode 0 or nonexistent inode\n");
- return;
+ return 0;
}
ino = inode->i_ino;
if (!(bh=inode->i_sb->u.minix_sb.s_imap[ino >> 13])) {
printk("free_inode: nonexistent imap in superblock\n");
- return;
+ return 0;
}
minix_clear_inode(inode);
clear_inode(inode);
if (!clear_bit(ino & 8191, bh->b_data))
printk("free_inode: bit %lu already cleared.\n",ino);
mark_buffer_dirty(bh, 1);
+ return 1;
}

struct inode * minix_new_inode(const struct inode * dir)
Index: linux/fs/minix/inode.c
diff -u linux/fs/minix/inode.c:1.1.1.1 linux/fs/minix/inode.c:1.2
--- linux/fs/minix/inode.c:1.1.1.1 Wed Nov 6 23:10:14 1996
+++ linux/fs/minix/inode.c Thu Nov 7 00:04:11 1996
@@ -21,13 +21,13 @@
#include <asm/segment.h>
#include <asm/bitops.h>

-void minix_put_inode(struct inode *inode)
+int minix_put_inode(struct inode *inode)
{
if (inode->i_nlink)
- return;
+ return 0;
inode->i_size = 0;
minix_truncate(inode);
- minix_free_inode(inode);
+ return minix_free_inode(inode);
}

static void minix_commit_super (struct super_block * sb,
Index: linux/fs/minix/namei.c
diff -u linux/fs/minix/namei.c:1.1.1.1 linux/fs/minix/namei.c:1.2
--- linux/fs/minix/namei.c:1.1.1.1 Wed Nov 6 23:10:14 1996
+++ linux/fs/minix/namei.c Thu Nov 7 00:04:12 1996
@@ -124,7 +124,7 @@
}
ino = de->inode;
brelse(bh);
- if (!(*result = iget(dir->i_sb,ino))) {
+ if (!(*result = __iget(dir->i_sb,ino,0))) {
iput(dir);
return -EACCES;
}
Index: linux/fs/msdos/namei.c
diff -u linux/fs/msdos/namei.c:1.1.1.1 linux/fs/msdos/namei.c:1.2
--- linux/fs/msdos/namei.c:1.1.1.1 Wed Nov 6 23:10:13 1996
+++ linux/fs/msdos/namei.c Thu Nov 7 00:04:21 1996
@@ -199,13 +199,13 @@
ino = fat_parent_ino(dir,0);
iput(dir);
if (ino < 0) return ino;
- if (!(*result = iget(dir->i_sb,ino))) return -EACCES;
+ if (!(*result = __iget(dir->i_sb,ino,0))) return -EACCES;
return 0;
}
#if 0
if (dcache_lookup(dir, name, len, (unsigned long *) &ino)) {
iput(dir);
- if (!(*result = iget(dir->i_sb, ino)))
+ if (!(*result = __iget(dir->i_sb, ino, 0)))
return -EACCES;
return 0;
}
@@ -219,7 +219,7 @@
if (bh)
fat_brelse(sb, bh);
PRINTK (("msdos_lookup 4.5\n"));
- if (!(*result = iget(dir->i_sb,ino))) {
+ if (!(*result = __iget(dir->i_sb,ino,0))) {
iput(dir);
return -EACCES;
}
@@ -239,7 +239,7 @@
while (MSDOS_I(*result)->i_old) {
next = MSDOS_I(*result)->i_old;
iput(*result);
- if (!(*result = iget(next->i_sb,next->i_ino))) {
+ if (!(*result = __iget(next->i_sb,next->i_ino,0))) {
fat_fs_panic(dir->i_sb,"msdos_lookup: Can't happen");
iput(dir);
return -ENOENT;
Index: linux/fs/ncpfs/dir.c
diff -u linux/fs/ncpfs/dir.c:1.1.1.1 linux/fs/ncpfs/dir.c:1.2
--- linux/fs/ncpfs/dir.c:1.1.1.1 Wed Nov 6 23:10:19 1996
+++ linux/fs/ncpfs/dir.c Thu Nov 7 00:04:23 1996
@@ -810,7 +810,7 @@
parent->state = NCP_INODE_LOOKED_UP;
}

- *result = iget(dir->i_sb, ncp_info_ino(server, parent));
+ *result = __iget(dir->i_sb, ncp_info_ino(server, parent), 0);
iput(dir);
if (*result == 0)
{
@@ -837,7 +837,7 @@
/* Here we convert the inode_info address into an
inode number */

- *result = iget(dir->i_sb, ncp_info_ino(server, result_info));
+ *result = __iget(dir->i_sb, ncp_info_ino(server, result_info), 0);
unlock_super(dir->i_sb);
iput(dir);

Index: linux/fs/ncpfs/inode.c
diff -u linux/fs/ncpfs/inode.c:1.1.1.1 linux/fs/ncpfs/inode.c:1.2
--- linux/fs/ncpfs/inode.c:1.1.1.1 Wed Nov 6 23:10:20 1996
+++ linux/fs/ncpfs/inode.c Thu Nov 7 00:04:23 1996
@@ -28,7 +28,7 @@

extern int close_fp(struct file *filp);

-static void ncp_put_inode(struct inode *);
+static int ncp_put_inode(struct inode *);
static void ncp_read_inode(struct inode *);
static void ncp_put_super(struct super_block *);
static void ncp_statfs(struct super_block *sb, struct statfs *buf, int bufsiz);
@@ -125,7 +125,7 @@
}
}

-static void
+static int
ncp_put_inode(struct inode *inode)
{
struct nw_file_info *finfo = NCP_FINFO(inode);
@@ -155,6 +155,7 @@

clear_inode(inode);
unlock_super(sb);
+ return 1;
}

struct super_block *
Index: linux/fs/nfs/inode.c
diff -u linux/fs/nfs/inode.c:1.1.1.1 linux/fs/nfs/inode.c:1.2
--- linux/fs/nfs/inode.c:1.1.1.1 Wed Nov 6 23:10:16 1996
+++ linux/fs/nfs/inode.c Thu Nov 7 00:04:24 1996
@@ -37,7 +37,7 @@
extern int close_fp(struct file *filp);

static int nfs_notify_change(struct inode *, struct iattr *);
-static void nfs_put_inode(struct inode *);
+static int nfs_put_inode(struct inode *);
static void nfs_put_super(struct super_block *);
static void nfs_read_inode(struct inode *);
static void nfs_statfs(struct super_block *, struct statfs *, int bufsiz);
@@ -73,12 +73,15 @@
NFS_CACHEINV(inode);
}

-static void nfs_put_inode(struct inode * inode)
+static int nfs_put_inode(struct inode * inode)
{
if (NFS_RENAMED_DIR(inode))
nfs_sillyrename_cleanup(inode);
- if (inode->i_pipe)
+ if (inode->i_pipe) {
clear_inode(inode);
+ return 1;
+ }
+ return 0;
}

void nfs_put_super(struct super_block *sb)
@@ -258,7 +261,7 @@
}
fattr = &newfattr;
}
- if (!(inode = iget(sb, fattr->fileid))) {
+ if (!(inode = __iget(sb, fattr->fileid, 0))) {
printk("nfs_fhget: iget failed\n");
return NULL;
}
Index: linux/fs/proc/inode.c
diff -u linux/fs/proc/inode.c:1.1.1.1 linux/fs/proc/inode.c:1.2
--- linux/fs/proc/inode.c:1.1.1.1 Wed Nov 6 23:10:14 1996
+++ linux/fs/proc/inode.c Thu Nov 7 00:04:26 1996
@@ -16,11 +16,12 @@
#include <asm/system.h>
#include <asm/segment.h>

-static void proc_put_inode(struct inode *inode)
+static int proc_put_inode(struct inode *inode)
{
if (inode->i_nlink)
- return;
+ return 0;
inode->i_size = 0;
+ return 0;
}

static void proc_put_super(struct super_block *sb)
@@ -73,7 +74,7 @@

struct inode * proc_get_inode(struct super_block * s, int ino, struct proc_dir_entry * de)
{
- struct inode * inode = iget(s, ino);
+ struct inode * inode = __iget(s, ino, 0);
if (inode && inode->i_sb == s) {
inode->u.generic_ip = (void *) de;
if (de) {
Index: linux/fs/proc/root.c
diff -u linux/fs/proc/root.c:1.1.1.1 linux/fs/proc/root.c:1.2
--- linux/fs/proc/root.c:1.1.1.1 Wed Nov 6 23:10:14 1996
+++ linux/fs/proc/root.c Thu Nov 7 00:04:26 1996
@@ -13,6 +13,7 @@
#include <linux/proc_fs.h>
#include <linux/stat.h>
#include <linux/config.h>
+#include <linux/utsname.h>
#include <asm/bitops.h>

/*
@@ -568,6 +569,17 @@

if (!p || !(pid = p->pid))
continue;
+#ifdef CONFIG_VIRT_HOSTNAME
+ if (current->sys_utsname &&
+ ( !p->sys_utsname ||
+ ( (current->sys_utsname != p->sys_utsname) &&
+ ( strcmp(current->sys_utsname->sys_utsname.nodename, p->sys_utsname->sys_utsname.nodename) ||
+ strcmp(current->sys_utsname->sys_utsname.domainname, p->sys_utsname->sys_utsname.domainname)
+ )
+ )
+ ))
+ continue; /* don't let processes on different virtual hosts show up */
+#endif

j = NUMBUF;
i = pid;
Index: linux/fs/smbfs/dir.c
diff -u linux/fs/smbfs/dir.c:1.1.1.1 linux/fs/smbfs/dir.c:1.2
--- linux/fs/smbfs/dir.c:1.1.1.1 Wed Nov 6 23:10:18 1996
+++ linux/fs/smbfs/dir.c Thu Nov 7 00:04:28 1996
@@ -665,7 +665,7 @@
/* Here we convert the inode_info address into an
inode number */

- *result = iget(dir->i_sb, (int)result_info);
+ *result = __iget(dir->i_sb, (int)result_info, 0);

if (new_inode_info != NULL)
{
Index: linux/fs/smbfs/inode.c
diff -u linux/fs/smbfs/inode.c:1.1.1.1 linux/fs/smbfs/inode.c:1.2
--- linux/fs/smbfs/inode.c:1.1.1.1 Wed Nov 6 23:10:19 1996
+++ linux/fs/smbfs/inode.c Thu Nov 7 00:04:29 1996
@@ -24,7 +24,7 @@

extern int close_fp(struct file *filp);

-static void smb_put_inode(struct inode *);
+static int smb_put_inode(struct inode *);
static void smb_read_inode(struct inode *);
static void smb_put_super(struct super_block *);
static void smb_statfs(struct super_block *, struct statfs *, int bufsiz);
@@ -118,7 +118,7 @@

}

-static void
+static int
smb_put_inode(struct inode *inode)
{
struct smb_dirent *finfo = SMB_FINFO(inode);
@@ -152,6 +152,7 @@
DPRINTK("smb_put_inode: could not close\n");
}
}
+ return 1;
}

static void
Index: linux/fs/sysv/ialloc.c
diff -u linux/fs/sysv/ialloc.c:1.1.1.1 linux/fs/sysv/ialloc.c:1.2
--- linux/fs/sysv/ialloc.c:1.1.1.1 Wed Nov 6 23:10:18 1996
+++ linux/fs/sysv/ialloc.c Thu Nov 7 00:04:31 1996
@@ -49,7 +49,7 @@
}
}

-void sysv_free_inode(struct inode * inode)
+int sysv_free_inode(struct inode * inode)
{
struct super_block * sb;
unsigned int ino;
@@ -57,33 +57,33 @@
struct sysv_inode * raw_inode;

if (!inode)
- return;
+ return 0;
if (!inode->i_dev) {
printk("sysv_free_inode: inode has no device\n");
- return;
+ return 0;
}
if (inode->i_count != 1) {
printk("sysv_free_inode: inode has count=%d\n", inode->i_count);
- return;
+ return 0;
}
if (inode->i_nlink) {
printk("sysv_free_inode: inode has nlink=%d\n", inode->i_nlink);
- return;
+ return 0;
}
if (!(sb = inode->i_sb)) {
printk("sysv_free_inode: inode on nonexistent device\n");
- return;
+ return 0;
}
ino = inode->i_ino;
if (ino <= SYSV_ROOT_INO || ino > sb->sv_ninodes) {
printk("sysv_free_inode: inode 0,1,2 or nonexistent inode\n");
- return;
+ return 0;
}
if (!(bh = sv_bread(sb, inode->i_dev, sb->sv_firstinodezone + ((ino-1) >> sb->sv_inodes_per_block_bits)))) {
printk("sysv_free_inode: unable to read inode block on device "
"%s\n", kdevname(inode->i_dev));
clear_inode(inode);
- return;
+ return 1;
}
raw_inode = (struct sysv_inode *) bh->b_data + ((ino-1) & sb->sv_inodes_per_block_1);
lock_super(sb);
@@ -98,6 +98,7 @@
unlock_super(sb);
brelse(bh);
clear_inode(inode);
+ return 1;
}

struct inode * sysv_new_inode(const struct inode * dir)
Index: linux/fs/sysv/inode.c
diff -u linux/fs/sysv/inode.c:1.1.1.1 linux/fs/sysv/inode.c:1.2
--- linux/fs/sysv/inode.c:1.1.1.1 Wed Nov 6 23:10:18 1996
+++ linux/fs/sysv/inode.c Thu Nov 7 00:04:32 1996
@@ -32,13 +32,13 @@

#include <asm/segment.h>

-void sysv_put_inode(struct inode *inode)
+int sysv_put_inode(struct inode *inode)
{
if (inode->i_nlink)
- return;
+ return 0;
inode->i_size = 0;
sysv_truncate(inode);
- sysv_free_inode(inode);
+ return sysv_free_inode(inode);
}


Index: linux/fs/sysv/namei.c
diff -u linux/fs/sysv/namei.c:1.1.1.1 linux/fs/sysv/namei.c:1.2
--- linux/fs/sysv/namei.c:1.1.1.1 Wed Nov 6 23:10:18 1996
+++ linux/fs/sysv/namei.c Thu Nov 7 00:04:32 1996
@@ -120,7 +120,7 @@
}
ino = de->inode;
brelse(bh);
- if (!(*result = iget(dir->i_sb,ino))) {
+ if (!(*result = __iget(dir->i_sb,ino,0))) {
iput(dir);
return -EACCES;
}
Index: linux/fs/ufs/ufs_dir.c
diff -u linux/fs/ufs/ufs_dir.c:1.1.1.1 linux/fs/ufs/ufs_dir.c:1.2
--- linux/fs/ufs/ufs_dir.c:1.1.1.1 Wed Nov 6 23:10:20 1996
+++ linux/fs/ufs/ufs_dir.c Thu Nov 7 00:04:34 1996
@@ -6,7 +6,7 @@
* Laboratory for Computer Science Research Computing Facility
* Rutgers, The State University of New Jersey
*
- * $Id: ufs_dir.c,v 1.1.1.1 1996/11/07 04:10:20 blah Exp $
+ * $Id: ufs_dir.c,v 1.2 1996/11/07 05:04:34 blah Exp $
*
*/

Index: linux/fs/ufs/ufs_file.c
diff -u linux/fs/ufs/ufs_file.c:1.1.1.1 linux/fs/ufs/ufs_file.c:1.2
--- linux/fs/ufs/ufs_file.c:1.1.1.1 Wed Nov 6 23:10:20 1996
+++ linux/fs/ufs/ufs_file.c Thu Nov 7 00:04:34 1996
@@ -6,7 +6,7 @@
* Laboratory for Computer Science Research Computing Facility
* Rutgers, The State University of New Jersey
*
- * $Id: ufs_file.c,v 1.1.1.1 1996/11/07 04:10:20 blah Exp $
+ * $Id: ufs_file.c,v 1.2 1996/11/07 05:04:34 blah Exp $
*
*/

Index: linux/fs/ufs/ufs_inode.c
diff -u linux/fs/ufs/ufs_inode.c:1.1.1.1 linux/fs/ufs/ufs_inode.c:1.3
--- linux/fs/ufs/ufs_inode.c:1.1.1.1 Wed Nov 6 23:10:21 1996
+++ linux/fs/ufs/ufs_inode.c Thu Nov 7 14:02:48 1996
@@ -6,7 +6,7 @@
* Laboratory for Computer Science Research Computing Facility
* Rutgers, The State University of New Jersey
*
- * $Id: ufs_inode.c,v 1.1.1.1 1996/11/07 04:10:21 blah Exp $
+ * $Id: ufs_inode.c,v 1.3 1996/11/07 19:02:48 blah Exp $
*
*/

@@ -206,10 +206,10 @@
return;
}

-void ufs_put_inode (struct inode * inode)
+int ufs_put_inode (struct inode * inode)
{
if (inode->i_nlink)
- return;
+ return 0;

printk("ufs_put_inode: nlink == 0 for inum %lu on dev %d/%d\n",
inode->i_ino, MAJOR(inode->i_dev), MINOR(inode->i_dev));
@@ -220,10 +220,10 @@
inode->i_size = 0;
if (inode->i_blocks)
ufs_truncate(inode);
- ufs_free_inode(inode);
+ return ufs_free_inode(inode);
*/

- return;
+ return 0;
}

/*
Index: linux/fs/ufs/ufs_namei.c
diff -u linux/fs/ufs/ufs_namei.c:1.1.1.1 linux/fs/ufs/ufs_namei.c:1.2
--- linux/fs/ufs/ufs_namei.c:1.1.1.1 Wed Nov 6 23:10:21 1996
+++ linux/fs/ufs/ufs_namei.c Thu Nov 7 00:04:35 1996
@@ -6,7 +6,7 @@
* Laboratory for Computer Science Research Computing Facility
* Rutgers, The State University of New Jersey
*
- * $Id: ufs_namei.c,v 1.1.1.1 1996/11/07 04:10:21 blah Exp $
+ * $Id: ufs_namei.c,v 1.2 1996/11/07 05:04:35 blah Exp $
*
*/

@@ -126,7 +126,7 @@
/* XXX - don't use strncmp() - see ext2fs */
(ufs_match(len, name, d))) {
/* We have a match */
- *result = iget(dir->i_sb, d->d_ino);
+ *result = __iget(dir->i_sb, d->d_ino, 0);
brelse(bh);
return(0);
} else {
Index: linux/fs/ufs/ufs_super.c
diff -u linux/fs/ufs/ufs_super.c:1.1.1.1 linux/fs/ufs/ufs_super.c:1.3
--- linux/fs/ufs/ufs_super.c:1.1.1.1 Wed Nov 6 23:10:20 1996
+++ linux/fs/ufs/ufs_super.c Thu Nov 7 14:02:49 1996
@@ -6,7 +6,7 @@
* Laboratory for Computer Science Research Computing Facility
* Rutgers, The State University of New Jersey
*
- * $Id: ufs_super.c,v 1.1.1.1 1996/11/07 04:10:20 blah Exp $
+ * $Id: ufs_super.c,v 1.3 1996/11/07 19:02:49 blah Exp $
*
*/

@@ -33,7 +33,7 @@
void ufs_statfs(struct super_block * sb, struct statfs * buf, int bufsize);

extern void ufs_read_inode(struct inode * inode);
-extern void ufs_put_inode(struct inode * inode);
+extern int ufs_put_inode(struct inode * inode);

static struct super_operations ufs_super_ops = {
ufs_read_inode,
Index: linux/fs/ufs/ufs_symlink.c
diff -u linux/fs/ufs/ufs_symlink.c:1.1.1.1 linux/fs/ufs/ufs_symlink.c:1.2
--- linux/fs/ufs/ufs_symlink.c:1.1.1.1 Wed Nov 6 23:10:21 1996
+++ linux/fs/ufs/ufs_symlink.c Thu Nov 7 00:04:36 1996
@@ -6,7 +6,7 @@
* Laboratory for Computer Science Research Computing Facility
* Rutgers, The State University of New Jersey
*
- * $Id: ufs_symlink.c,v 1.1.1.1 1996/11/07 04:10:21 blah Exp $
+ * $Id: ufs_symlink.c,v 1.2 1996/11/07 05:04:36 blah Exp $
*
*/

Index: linux/fs/umsdos/inode.c
diff -u linux/fs/umsdos/inode.c:1.1.1.1 linux/fs/umsdos/inode.c:1.2
--- linux/fs/umsdos/inode.c:1.1.1.1 Wed Nov 6 23:10:18 1996
+++ linux/fs/umsdos/inode.c Thu Nov 7 14:29:45 1996
@@ -36,7 +36,7 @@
#define Printk(x) printk x


-void UMSDOS_put_inode(struct inode *inode)
+int UMSDOS_put_inode(struct inode *inode)
{
PRINTK (("put inode %x owner %x pos %d dir %x\n",inode
,inode->u.umsdos_i.i_emd_owner,inode->u.umsdos_i.pos
@@ -44,7 +44,7 @@
if (inode != NULL && inode == pseudo_root){
printk ("Umsdos: Oops releasing pseudo_root. Notify jacques@solucorp.qc.ca\n");
}
- fat_put_inode(inode);
+ return fat_put_inode(inode);
}


Index: linux/fs/umsdos/namei.c
diff -u linux/fs/umsdos/namei.c:1.1.1.1 linux/fs/umsdos/namei.c:1.2
--- linux/fs/umsdos/namei.c:1.1.1.1 Wed Nov 6 23:10:18 1996
+++ linux/fs/umsdos/namei.c Thu Nov 7 00:04:39 1996
@@ -963,8 +963,7 @@
PRINTK (("unlink nlink = %d ",inode->i_nlink));
inode->i_nlink--;
if (inode->i_nlink == 0){
- struct inode *hdir = iget(inode->i_sb
- ,inode->u.umsdos_i.i_dir_owner);
+ struct inode *hdir = __iget(inode->i_sb,inode->u.umsdos_i.i_dir_owner,0);
struct umsdos_dirent entry;
ret = umsdos_inode2entry (hdir,inode,&entry);
if (ret == 0){
Index: linux/fs/vfat/namei.c
diff -u linux/fs/vfat/namei.c:1.1.1.1 linux/fs/vfat/namei.c:1.2
--- linux/fs/vfat/namei.c:1.1.1.1 Wed Nov 6 23:10:21 1996
+++ linux/fs/vfat/namei.c Thu Nov 7 00:04:50 1996
@@ -930,12 +930,12 @@
ino = fat_parent_ino(dir,0);
iput(dir);
if (ino < 0) return ino;
- if (!(*result = iget(dir->i_sb,ino))) return -EACCES;
+ if (!(*result = __iget(dir->i_sb,ino,0))) return -EACCES;
return 0;
}
if (dcache_lookup(dir, name, len, (unsigned long *) &ino) && ino) {
iput(dir);
- if (!(*result = iget(dir->i_sb, ino)))
+ if (!(*result = __iget(dir->i_sb, ino, 0)))
return -EACCES;
return 0;
}
@@ -945,7 +945,7 @@
return res;
}
PRINTK (("vfat_lookup 4.5\n"));
- if (!(*result = iget(dir->i_sb,sinfo.ino))) {
+ if (!(*result = __iget(dir->i_sb,sinfo.ino,0))) {
iput(dir);
return -EACCES;
}
@@ -965,7 +965,7 @@
while (MSDOS_I(*result)->i_old) {
next = MSDOS_I(*result)->i_old;
iput(*result);
- if (!(*result = iget(next->i_sb,next->i_ino))) {
+ if (!(*result = __iget(next->i_sb,next->i_ino,0))) {
fat_fs_panic(dir->i_sb,"vfat_lookup: Can't happen");
iput(dir);
return -ENOENT;
Index: linux/fs/xiafs/bitmap.c
diff -u linux/fs/xiafs/bitmap.c:1.1.1.1 linux/fs/xiafs/bitmap.c:1.2
--- linux/fs/xiafs/bitmap.c:1.1.1.1 Wed Nov 6 23:10:16 1996
+++ linux/fs/xiafs/bitmap.c Thu Nov 7 00:04:54 1996
@@ -275,25 +275,25 @@
return tmp;
}

-void xiafs_free_inode(struct inode * inode)
+int xiafs_free_inode(struct inode * inode)
{
struct buffer_head * bh;
struct super_block * sb;
unsigned long ino;

if (!inode)
- return;
+ return 0;
if (!inode->i_dev || inode->i_count!=1
|| inode->i_nlink || !inode->i_sb || inode->i_ino < 3
|| inode->i_ino > inode->i_sb->u.xiafs_sb.s_ninodes) {
printk("XIA-FS: bad inode (%s %d)\n", WHERE_ERR);
- return;
+ return 0;
}
sb = inode->i_sb;
ino = inode->i_ino;
bh = get_imap_zone(sb, ino, NULL);
if (!bh)
- return;
+ return 0;
clear_inode(inode);
if (!clear_bit(ino & (XIAFS_BITS_PER_Z(sb)-1), bh->b_data))
printk("XIA-FS: dev %s"
@@ -301,6 +301,7 @@
kdevname(inode->i_dev), ino, ino, WHERE_ERR);
mark_buffer_dirty(bh, 1);
xiafs_unlock_super(sb, sb->u.xiafs_sb.s_imap_cached);
+ return 1;
}

struct inode * xiafs_new_inode(struct inode * dir)
Index: linux/fs/xiafs/inode.c
diff -u linux/fs/xiafs/inode.c:1.1.1.1 linux/fs/xiafs/inode.c:1.2
--- linux/fs/xiafs/inode.c:1.1.1.1 Wed Nov 6 23:10:16 1996
+++ linux/fs/xiafs/inode.c Thu Nov 7 00:04:54 1996
@@ -25,13 +25,13 @@

static u_long random_nr;

-void xiafs_put_inode(struct inode *inode)
+int xiafs_put_inode(struct inode *inode)
{
if (inode->i_nlink)
- return;
+ return 0;
inode->i_size = 0;
xiafs_truncate(inode);
- xiafs_free_inode(inode);
+ return xiafs_free_inode(inode);
}

void xiafs_put_super(struct super_block *sb)
Index: linux/fs/xiafs/namei.c
diff -u linux/fs/xiafs/namei.c:1.1.1.1 linux/fs/xiafs/namei.c:1.2
--- linux/fs/xiafs/namei.c:1.1.1.1 Wed Nov 6 23:10:16 1996
+++ linux/fs/xiafs/namei.c Thu Nov 7 00:04:55 1996
@@ -133,7 +133,7 @@
}
ino = dep->d_ino;
brelse(bh);
- if (!(*result = iget(dir->i_sb, ino))) {
+ if (!(*result = __iget(dir->i_sb, ino, 0))) {
iput(dir);
return -EACCES;
}
Index: linux/include/linux/affs_fs.h
diff -u linux/include/linux/affs_fs.h:1.1.1.1 linux/include/linux/affs_fs.h:1.2
--- linux/include/linux/affs_fs.h:1.1.1.1 Wed Nov 6 23:10:23 1996
+++ linux/include/linux/affs_fs.h Thu Nov 7 12:35:44 1996
@@ -83,7 +83,7 @@
extern void affs_read_inode(struct inode *);
extern void affs_write_inode(struct inode *);
extern int affs_notify_change(struct inode *inode, struct iattr *attr);
-extern void affs_put_inode(struct inode *);
+extern int affs_put_inode(struct inode *);
extern struct inode *affs_new_inode(const struct inode *dir);
extern int affs_add_entry(struct inode *dir, struct inode *link, struct inode *inode,
const char *name, int len, int type);
Index: linux/include/linux/ext2_fs.h
diff -u linux/include/linux/ext2_fs.h:1.1.1.1 linux/include/linux/ext2_fs.h:1.2
--- linux/include/linux/ext2_fs.h:1.1.1.1 Wed Nov 6 23:10:24 1996
+++ linux/include/linux/ext2_fs.h Thu Nov 7 12:35:45 1996
@@ -462,7 +462,7 @@

/* ialloc.c */
extern struct inode * ext2_new_inode (const struct inode *, int, int *);
-extern void ext2_free_inode (struct inode *);
+extern int ext2_free_inode (struct inode *);
extern unsigned long ext2_count_free_inodes (struct super_block *);
extern void ext2_check_inodes_bitmap (struct super_block *);

@@ -475,7 +475,7 @@
extern int ext2_getcluster (struct inode * inode, long block);
extern void ext2_read_inode (struct inode *);
extern void ext2_write_inode (struct inode *);
-extern void ext2_put_inode (struct inode *);
+extern int ext2_put_inode (struct inode *);
extern int ext2_sync_inode (struct inode *);
extern void ext2_discard_prealloc (struct inode *);

Index: linux/include/linux/ext_fs.h
diff -u linux/include/linux/ext_fs.h:1.1.1.1 linux/include/linux/ext_fs.h:1.2
--- linux/include/linux/ext_fs.h:1.1.1.1 Wed Nov 6 23:10:23 1996
+++ linux/include/linux/ext_fs.h Thu Nov 7 12:35:45 1996
@@ -76,7 +76,7 @@
extern int ext_rename(struct inode * old_dir, const char * old_name, int old_len,
struct inode * new_dir, const char * new_name, int new_len, int must_be_dir);
extern struct inode * ext_new_inode(const struct inode * dir);
-extern void ext_free_inode(struct inode * inode);
+extern int ext_free_inode(struct inode * inode);
extern unsigned long ext_count_free_inodes(struct super_block *sb);
extern int ext_new_block(struct super_block * sb);
extern void ext_free_block(struct super_block * sb, int block);
@@ -94,7 +94,7 @@
extern int init_ext_fs(void);
extern void ext_read_inode(struct inode *);
extern void ext_write_inode(struct inode *);
-extern void ext_put_inode(struct inode *);
+extern int ext_put_inode(struct inode *);
extern void ext_statfs(struct super_block *, struct statfs *, int);
extern int ext_sync_inode(struct inode *);
extern int ext_sync_file(struct inode *, struct file *);
Index: linux/include/linux/fs.h
diff -u linux/include/linux/fs.h:1.1.1.1 linux/include/linux/fs.h:1.3
--- linux/include/linux/fs.h:1.1.1.1 Wed Nov 6 23:10:23 1996
+++ linux/include/linux/fs.h Thu Nov 7 17:42:12 1996
@@ -494,7 +494,7 @@
void (*read_inode) (struct inode *);
int (*notify_change) (struct inode *, struct iattr *);
void (*write_inode) (struct inode *);
- void (*put_inode) (struct inode *);
+ int (*put_inode) (struct inode *);
void (*put_super) (struct super_block *);
void (*write_super) (struct super_block *);
void (*statfs) (struct super_block *, struct statfs *, int);
@@ -609,6 +609,7 @@
extern void sync_supers(kdev_t dev);
extern int bmap(struct inode * inode,int block);
extern int notify_change(struct inode *, struct iattr *);
+extern int _namei(const char * pathname, struct inode * base, int follow_links, struct inode ** res_inode);
extern int namei(const char * pathname, struct inode ** res_inode);
extern int lnamei(const char * pathname, struct inode ** res_inode);
extern int permission(struct inode * inode,int mask);
Index: linux/include/linux/minix_fs.h
diff -u linux/include/linux/minix_fs.h:1.1.1.1 linux/include/linux/minix_fs.h:1.2
--- linux/include/linux/minix_fs.h:1.1.1.1 Wed Nov 6 23:10:23 1996
+++ linux/include/linux/minix_fs.h Thu Nov 7 12:35:46 1996
@@ -102,7 +102,7 @@
extern int minix_rename(struct inode * old_dir, const char * old_name, int old_len,
struct inode * new_dir, const char * new_name, int new_len, int must_be_dir);
extern struct inode * minix_new_inode(const struct inode * dir);
-extern void minix_free_inode(struct inode * inode);
+extern int minix_free_inode(struct inode * inode);
extern unsigned long minix_count_free_inodes(struct super_block *sb);
extern int minix_new_block(struct super_block * sb);
extern void minix_free_block(struct super_block * sb, int block);
@@ -121,7 +121,7 @@
extern int minix_remount (struct super_block * sb, int * flags, char * data);
extern void minix_read_inode(struct inode *);
extern void minix_write_inode(struct inode *);
-extern void minix_put_inode(struct inode *);
+extern int minix_put_inode(struct inode *);
extern void minix_statfs(struct super_block *, struct statfs *, int);
extern int minix_sync_inode(struct inode *);
extern int minix_sync_file(struct inode *, struct file *);
Index: linux/include/linux/msdos_fs.h
diff -u linux/include/linux/msdos_fs.h:1.1.1.1 linux/include/linux/msdos_fs.h:1.2
--- linux/include/linux/msdos_fs.h:1.1.1.1 Wed Nov 6 23:10:23 1996
+++ linux/include/linux/msdos_fs.h Thu Nov 7 12:35:46 1996
@@ -200,7 +200,7 @@
/* inode.c */
extern int fat_bmap(struct inode *inode,int block);
extern int fat_notify_change(struct inode *,struct iattr *);
-extern void fat_put_inode(struct inode *inode);
+extern int fat_put_inode(struct inode *inode);
extern void fat_put_super(struct super_block *sb);
extern void fat_read_inode(struct inode *inode, struct inode_operations *dir_ops);
extern struct super_block *fat_read_super(struct super_block *s, void *data, int silent);
Index: linux/include/linux/sysv_fs.h
diff -u linux/include/linux/sysv_fs.h:1.1.1.1 linux/include/linux/sysv_fs.h:1.2
--- linux/include/linux/sysv_fs.h:1.1.1.1 Wed Nov 6 23:10:25 1996
+++ linux/include/linux/sysv_fs.h Thu Nov 7 12:35:46 1996
@@ -375,7 +375,7 @@
extern int sysv_rename(struct inode * old_dir, const char * old_name, int old_len,
struct inode * new_dir, const char * new_name, int new_len, int must_be_dir);
extern struct inode * sysv_new_inode(const struct inode * dir);
-extern void sysv_free_inode(struct inode * inode);
+extern int sysv_free_inode(struct inode * inode);
extern unsigned long sysv_count_free_inodes(struct super_block *sb);
extern int sysv_new_block(struct super_block * sb);
extern void sysv_free_block(struct super_block * sb, unsigned int block);
@@ -395,7 +395,7 @@
extern void sysv_read_inode(struct inode *);
extern int sysv_notify_change(struct inode *, struct iattr *);
extern void sysv_write_inode(struct inode *);
-extern void sysv_put_inode(struct inode *);
+extern int sysv_put_inode(struct inode *);
extern void sysv_statfs(struct super_block *, struct statfs *, int);
extern int sysv_sync_inode(struct inode *);
extern int sysv_sync_file(struct inode *, struct file *);
Index: linux/include/linux/umsdos_fs.p
diff -u linux/include/linux/umsdos_fs.p:1.1.1.1 linux/include/linux/umsdos_fs.p:1.2
--- linux/include/linux/umsdos_fs.p:1.1.1.1 Wed Nov 6 23:10:26 1996
+++ linux/include/linux/umsdos_fs.p Thu Nov 7 14:45:21 1996
@@ -55,7 +55,7 @@
int expect);
/* file.c 25/01/95 02.25.38 */
/* inode.c 12/06/95 09.49.40 */
-void UMSDOS_put_inode (struct inode *inode);
+int UMSDOS_put_inode (struct inode *inode);
void UMSDOS_put_super (struct super_block *sb);
void UMSDOS_statfs (struct super_block *sb,
struct statfs *buf,
Index: linux/include/linux/xia_fs.h
diff -u linux/include/linux/xia_fs.h:1.1.1.1 linux/include/linux/xia_fs.h:1.2
--- linux/include/linux/xia_fs.h:1.1.1.1 Wed Nov 6 23:10:24 1996
+++ linux/include/linux/xia_fs.h Thu Nov 7 12:35:47 1996
@@ -82,7 +82,7 @@
const char * new_name, int new_len,
int must_be_dir);
extern struct inode * xiafs_new_inode(struct inode * dir);
-extern void xiafs_free_inode(struct inode * inode);
+extern int xiafs_free_inode(struct inode * inode);
extern unsigned long xiafs_count_free_inodes(struct super_block *sb);
extern int xiafs_new_zone(struct super_block * sb, u_long prev_addr);
extern void xiafs_free_zone(struct super_block * sb, int block);
@@ -99,7 +99,7 @@
extern int init_xiafs_fs(void);
extern void xiafs_read_inode(struct inode *);
extern void xiafs_write_inode(struct inode *);
-extern void xiafs_put_inode(struct inode *);
+extern int xiafs_put_inode(struct inode *);
extern void xiafs_statfs(struct super_block *, struct statfs *, int);
extern int xiafs_sync_inode(struct inode *);
extern int xiafs_sync_file(struct inode *, struct file *);
Index: linux/kernel/ksyms.c
diff -u linux/kernel/ksyms.c:1.1.1.1 linux/kernel/ksyms.c:1.3
--- linux/kernel/ksyms.c:1.1.1.1 Wed Nov 6 23:10:21 1996
+++ linux/kernel/ksyms.c Thu Nov 7 19:46:19 1996
@@ -46,6 +46,7 @@
#include <linux/genhd.h>
#include <linux/swap.h>
#include <linux/ctype.h>
+#include <linux/file.h>

extern unsigned char aux_device_present, kbd_read_mask;

@@ -141,6 +142,9 @@
X(putname),
X(__iget),
X(iput),
+ X(get_empty_filp),
+ X(__fput),
+ X(_namei),
X(namei),
X(lnamei),
X(open_namei),
@@ -154,6 +158,7 @@
X(permission),
X(inode_setattr),
X(inode_change_ok),
+ X(notify_change),
X(set_blocksize),
X(getblk),
X(bread),