diff -u --recursive --new-file v2.1.77/linux/Documentation/networking/depca.txt linux/Documentation/networking/depca.txt --- v2.1.77/linux/Documentation/networking/depca.txt Wed Dec 31 16:00:00 1969 +++ linux/Documentation/networking/depca.txt Sat Jan 3 20:49:41 1998 @@ -0,0 +1,92 @@ + +DE10x +===== + +Memory Addresses: + + SW1 SW2 SW3 SW4 +64K on on on on d0000 dbfff + off on on on c0000 cbfff + off off on on e0000 ebfff + +32K on on off on d8000 dbfff + off on off on c8000 cbfff + off off off on e8000 ebfff + +DBR ROM on on dc000 dffff + off on cc000 cffff + off off ec000 effff + +Note that the 2K mode is set by SW3/SW4 on/off or off/off. Address +assignment is through the RBSA register. + +I/O Address: + SW5 +0x300 on +0x200 off + +Remote Boot: + SW6 +Disable on +Enable off + +Remote Boot Timeout: + SW7 +2.5min on +30s off + +IRQ: + SW8 SW9 SW10 SW11 SW12 +2 on off off off off +3 off on off off off +4 off off on off off +5 off off off on off +7 off off off off on + +DE20x +===== + +Memory Size: + + SW3 SW4 +64K on on +32K off on +2K on off +2K off off + +Start Addresses: + + SW1 SW2 SW3 SW4 +64K on on on on c0000 cffff + on off on on d0000 dffff + off on on on e0000 effff + +32K on on off off c8000 cffff + on off off off d8000 dffff + off on off off e8000 effff + +Illegal off off - - - - + +I/O Address: + SW5 +0x300 on +0x200 off + +Remote Boot: + SW6 +Disable on +Enable off + +Remote Boot Timeout: + SW7 +2.5min on +30s off + +IRQ: + SW8 SW9 SW10 SW11 SW12 +5 on off off off off +9 off on off off off +10 off off on off off +11 off off off on off +15 off off off off on + diff -u --recursive --new-file v2.1.77/linux/Makefile linux/Makefile --- v2.1.77/linux/Makefile Fri Jan 2 14:37:01 1998 +++ linux/Makefile Sun Jan 4 01:50:55 1998 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 1 -SUBLEVEL = 77 +SUBLEVEL = 78 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/) diff -u --recursive --new-file v2.1.77/linux/fs/affs/inode.c linux/fs/affs/inode.c --- v2.1.77/linux/fs/affs/inode.c Thu Dec 4 14:53:56 1997 +++ linux/fs/affs/inode.c Sun Jan 4 00:53:42 1998 @@ -220,8 +220,9 @@ } int -affs_notify_change(struct inode *inode, struct iattr *attr) +affs_notify_change(struct dentry *dentry, struct iattr *attr) { + struct inode *inode = dentry->d_inode; int error; pr_debug("AFFS: notify_change(%lu,0x%x)\n",inode->i_ino,attr->ia_valid); diff -u --recursive --new-file v2.1.77/linux/fs/affs/symlink.c linux/fs/affs/symlink.c --- v2.1.77/linux/fs/affs/symlink.c Thu Dec 4 14:53:56 1997 +++ linux/fs/affs/symlink.c Sun Jan 4 00:53:42 1998 @@ -19,8 +19,8 @@ #define MIN(a,b) (((a) < (b)) ? (a) : (b)) -static int affs_readlink(struct inode *, char *, int); -static struct dentry *affs_follow_link(struct inode *inode, struct dentry *base); +static int affs_readlink(struct dentry *, char *, int); +static struct dentry *affs_follow_link(struct dentry *dentry, struct dentry *base); struct inode_operations affs_symlink_inode_operations = { NULL, /* no file-operations */ @@ -44,8 +44,9 @@ }; static int -affs_readlink(struct inode *inode, char *buffer, int buflen) +affs_readlink(struct inode *dentry, char *buffer, int buflen) { + struct inode *inode = dentry->d_inode; struct buffer_head *bh; struct slink_front *lf; int i, j; @@ -97,8 +98,9 @@ } static struct dentry * -affs_follow_link(struct inode *inode, struct dentry *base) +affs_follow_link(struct dentry *dentry, struct dentry *base) { + struct inode *inode = dentry->d_inode; struct buffer_head *bh; struct slink_front *lf; char *buffer; diff -u --recursive --new-file v2.1.77/linux/fs/attr.c linux/fs/attr.c --- v2.1.77/linux/fs/attr.c Sun Dec 21 22:36:15 1997 +++ linux/fs/attr.c Sun Jan 4 00:53:41 1998 @@ -81,8 +81,9 @@ mark_inode_dirty(inode); } -int notify_change(struct inode * inode, struct iattr * attr) +int notify_change(struct dentry * dentry, struct iattr * attr) { + struct inode *inode = dentry->d_inode; int error; time_t now = CURRENT_TIME; unsigned int ia_valid = attr->ia_valid; @@ -93,11 +94,13 @@ if (!(ia_valid & ATTR_MTIME_SET)) attr->ia_mtime = now; - if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->notify_change) - return inode->i_sb->s_op->notify_change(inode, attr); - - error = inode_change_ok(inode, attr); - if (!error) - inode_setattr(inode, attr); + if (inode->i_sb && inode->i_sb->s_op && + inode->i_sb->s_op->notify_change) + error = inode->i_sb->s_op->notify_change(dentry, attr); + else { + error = inode_change_ok(inode, attr); + if (!error) + inode_setattr(inode, attr); + } return error; } diff -u --recursive --new-file v2.1.77/linux/fs/autofs/symlink.c linux/fs/autofs/symlink.c --- v2.1.77/linux/fs/autofs/symlink.c Mon Aug 4 16:25:38 1997 +++ linux/fs/autofs/symlink.c Sun Jan 4 00:53:43 1998 @@ -14,23 +14,24 @@ #include #include "autofs_i.h" -static int autofs_readlink(struct inode *inode, char *buffer, int buflen) +static int autofs_readlink(struct dentry *dentry, char *buffer, int buflen) { struct autofs_symlink *sl; int len; - sl = (struct autofs_symlink *)inode->u.generic_ip; + sl = (struct autofs_symlink *)dentry->d_inode->u.generic_ip; len = sl->len; if (len > buflen) len = buflen; - copy_to_user(buffer,sl->data,len); + copy_to_user(buffer, sl->data, len); return len; } -static struct dentry * autofs_follow_link(struct inode *inode, struct dentry *base) +static struct dentry * autofs_follow_link(struct dentry *dentry, + struct dentry *base) { struct autofs_symlink *sl; - sl = (struct autofs_symlink *)inode->u.generic_ip; + sl = (struct autofs_symlink *)dentry->d_inode->u.generic_ip; return lookup_dentry(sl->data, base, 1); } diff -u --recursive --new-file v2.1.77/linux/fs/bad_inode.c linux/fs/bad_inode.c --- v2.1.77/linux/fs/bad_inode.c Wed Oct 15 16:04:23 1997 +++ linux/fs/bad_inode.c Sun Jan 4 00:53:41 1998 @@ -13,7 +13,7 @@ /* * The follow_symlink operation must dput() the base. */ -static struct dentry * bad_follow_link(struct inode * ino, struct dentry *base) +static struct dentry * bad_follow_link(struct dentry *dent, struct dentry *base) { dput(base); return ERR_PTR(-EIO); diff -u --recursive --new-file v2.1.77/linux/fs/buffer.c linux/fs/buffer.c --- v2.1.77/linux/fs/buffer.c Tue Dec 23 16:31:00 1997 +++ linux/fs/buffer.c Sun Jan 4 00:53:57 1998 @@ -1522,8 +1522,9 @@ * mark_buffer_uptodate() functions propagate buffer state into the * page struct once IO has completed. */ -int generic_readpage(struct inode * inode, struct page * page) +int generic_readpage(struct dentry * dentry, struct page * page) { + struct inode *inode = dentry->d_inode; unsigned long block; int *p, nr[PAGE_SIZE/512]; int i; diff -u --recursive --new-file v2.1.77/linux/fs/coda/file.c linux/fs/coda/file.c --- v2.1.77/linux/fs/coda/file.c Sun Dec 21 22:36:16 1997 +++ linux/fs/coda/file.c Sun Jan 4 00:53:43 1998 @@ -25,10 +25,10 @@ #include /* file operations */ -static int coda_readpage(struct inode * inode, 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); +static int coda_readpage(struct dentry *, struct page *); +static ssize_t coda_file_read(struct file *, char *, size_t, loff_t *); +static ssize_t coda_file_write(struct file *, const char *, size_t, loff_t *); +static int coda_file_mmap(struct file *, struct vm_area_struct *); /* exported from this file */ int coda_fsync(struct file *, struct dentry *dentry); @@ -74,9 +74,9 @@ }; /* File file operations */ -static int coda_readpage(struct inode * inode, struct page * page) +static int coda_readpage(struct dentry *dentry, struct page * page) { - struct inode *open_inode; + struct inode *open_inode, *inode = dentry->d_inode; struct cnode *cnp; ENTRY; @@ -93,6 +93,7 @@ CDEBUG(D_INODE, "coda ino: %ld, cached ino %ld, page offset: %lx\n", inode->i_ino, open_inode->i_ino, page->offset); + /* N.B. This needs the dentry for open_inode */ generic_readpage(open_inode, page); EXIT; return 0; diff -u --recursive --new-file v2.1.77/linux/fs/coda/super.c linux/fs/coda/super.c --- v2.1.77/linux/fs/coda/super.c Sun Dec 21 22:36:16 1997 +++ linux/fs/coda/super.c Sun Jan 4 00:53:43 1998 @@ -41,7 +41,7 @@ /* VFS super_block ops */ static struct super_block *coda_read_super(struct super_block *, void *, int); static void coda_read_inode(struct inode *); -static int coda_notify_change(struct inode *inode, struct iattr *attr); +static int coda_notify_change(struct dentry *, struct iattr *); static void coda_put_inode(struct inode *); static void coda_delete_inode(struct inode *); static void coda_put_super(struct super_block *); @@ -133,6 +133,7 @@ printk("coda_read_super: rootinode is %ld dev %d\n", root->i_ino, root->i_dev); sbi->sbi_root = root; + /* N.B. check this for failure */ sb->s_root = d_alloc_root(root, NULL); unlock_super(sb); EXIT; @@ -140,7 +141,6 @@ error: EXIT; - MOD_DEC_USE_COUNT; if (sbi) { sbi->sbi_vcomm = NULL; sbi->sbi_root = NULL; @@ -154,6 +154,7 @@ coda_cnode_free(ITOC(root)); } sb->s_dev = 0; + MOD_DEC_USE_COUNT; return NULL; } @@ -224,8 +225,9 @@ EXIT; } -static int coda_notify_change(struct inode *inode, struct iattr *iattr) +static int coda_notify_change(struct dentry *dentry, struct iattr *iattr) { + struct inode *inode = dentry->d_inode; struct cnode *cnp; struct coda_vattr vattr; int error; diff -u --recursive --new-file v2.1.77/linux/fs/coda/symlink.c linux/fs/coda/symlink.c --- v2.1.77/linux/fs/coda/symlink.c Sun Dec 21 22:36:16 1997 +++ linux/fs/coda/symlink.c Sun Jan 4 00:53:43 1998 @@ -24,8 +24,8 @@ #include #include -static int coda_readlink(struct inode *inode, char *buffer, int length); -static struct dentry *coda_follow_link(struct inode *, struct dentry *); +static int coda_readlink(struct dentry *dentry, char *buffer, int length); +static struct dentry *coda_follow_link(struct dentry *, struct dentry *); struct inode_operations coda_symlink_inode_operations = { NULL, /* no file-operations */ @@ -50,8 +50,9 @@ NULL /* revalidate */ }; -static int coda_readlink(struct inode *inode, char *buffer, int length) +static int coda_readlink(struct inode *dentry, char *buffer, int length) { + struct inode *inode = dentry->d_inode; int len; int error; char *buf; @@ -83,14 +84,15 @@ return error; } -static struct dentry *coda_follow_link(struct inode *inode, - struct dentry *base) +static struct dentry *coda_follow_link(struct dentry *dentry, + struct dentry *base) { + struct inode *inode = dentry->d_inode; int error; struct cnode *cnp; unsigned int len; - char mem[CFS_MAXPATHLEN]; char *path; + char mem[CFS_MAXPATHLEN]; /* N.B. too big for the stack? */ ENTRY; CDEBUG(D_INODE, "(%x/%ld)\n", inode->i_dev, inode->i_ino); diff -u --recursive --new-file v2.1.77/linux/fs/dcache.c linux/fs/dcache.c --- v2.1.77/linux/fs/dcache.c Fri Dec 19 15:53:00 1997 +++ linux/fs/dcache.c Sun Jan 4 00:54:04 1998 @@ -52,6 +52,8 @@ static inline void d_free(struct dentry *dentry) { + if (dentry->d_op && dentry->d_op->d_release) + dentry->d_op->d_release(dentry); kfree(dentry->d_name.name); kfree(dentry); } @@ -502,6 +504,7 @@ dentry->d_name.len = name->len; dentry->d_name.hash = name->hash; dentry->d_op = NULL; + dentry->d_fsdata = NULL; return dentry; } diff -u --recursive --new-file v2.1.77/linux/fs/ext2/inode.c linux/fs/ext2/inode.c --- v2.1.77/linux/fs/ext2/inode.c Sun Dec 21 22:36:16 1997 +++ linux/fs/ext2/inode.c Sun Jan 4 00:53:41 1998 @@ -631,23 +631,25 @@ return ext2_update_inode (inode, 1); } -int ext2_notify_change(struct inode *inode, struct iattr *iattr) +int ext2_notify_change(struct dentry *dentry, struct iattr *iattr) { + struct inode *inode = dentry->d_inode; int retval; unsigned int flags; + retval = -EPERM; if ((iattr->ia_attr_flags & (ATTR_FLAG_APPEND | ATTR_FLAG_IMMUTABLE)) ^ (inode->u.ext2_i.i_flags & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL))) { if (securelevel > 0 || !fsuser()) - return -EPERM; - } else - if ((current->fsuid != inode->i_uid) && !fsuser()) - return -EPERM; + goto out; + } else if ((current->fsuid != inode->i_uid) && !fsuser()) + goto out; - if ((retval = inode_change_ok(inode, iattr)) != 0) - return retval; + retval = inode_change_ok(inode, iattr); + if (retval != 0) + goto out; inode_setattr(inode, iattr); @@ -681,7 +683,7 @@ inode->u.ext2_i.i_flags &= ~EXT2_IMMUTABLE_FL; } mark_inode_dirty(inode); - - return 0; +out: + return retval; } diff -u --recursive --new-file v2.1.77/linux/fs/ext2/namei.c linux/fs/ext2/namei.c --- v2.1.77/linux/fs/ext2/namei.c Sat Nov 29 11:25:12 1997 +++ linux/fs/ext2/namei.c Sun Jan 4 00:53:41 1998 @@ -793,8 +793,10 @@ goto out; } -int ext2_link (struct inode * inode, struct inode * dir, struct dentry *dentry) +int ext2_link (struct dentry * old_dentry, + struct inode * dir, struct dentry *dentry) { + struct inode *inode = old_dentry->d_inode; struct ext2_dir_entry * de; struct buffer_head * bh; int err; diff -u --recursive --new-file v2.1.77/linux/fs/ext2/symlink.c linux/fs/ext2/symlink.c --- v2.1.77/linux/fs/ext2/symlink.c Thu Jul 17 10:06:06 1997 +++ linux/fs/ext2/symlink.c Sun Jan 4 00:53:41 1998 @@ -24,8 +24,8 @@ #include #include -static int ext2_readlink (struct inode *, char *, int); -static struct dentry *ext2_follow_link(struct inode *, struct dentry *); +static int ext2_readlink (struct dentry *, char *, int); +static struct dentry *ext2_follow_link(struct dentry *, struct dentry *); /* * symlinks can't do much... @@ -51,10 +51,12 @@ NULL /* smap */ }; -static struct dentry * ext2_follow_link(struct inode * inode, struct dentry *base) +static struct dentry * ext2_follow_link(struct dentry * dentry, + struct dentry *base) { - int error; + struct inode *inode = dentry->d_inode; struct buffer_head * bh = NULL; + int error; char * link; link = (char *) inode->u.ext2_i.i_data; @@ -72,8 +74,9 @@ return base; } -static int ext2_readlink (struct inode * inode, char * buffer, int buflen) +static int ext2_readlink (struct dentry * dentry, char * buffer, int buflen) { + struct inode *inode = dentry->d_inode; struct buffer_head * bh = NULL; char * link; int i; diff -u --recursive --new-file v2.1.77/linux/fs/fat/inode.c linux/fs/fat/inode.c --- v2.1.77/linux/fs/fat/inode.c Sun Dec 21 22:36:16 1997 +++ linux/fs/fat/inode.c Sun Jan 4 00:53:42 1998 @@ -783,9 +783,10 @@ } -int fat_notify_change(struct inode * inode,struct iattr * attr) +int fat_notify_change(struct dentry * dentry, struct iattr * attr) { - struct super_block *sb = inode->i_sb; + struct super_block *sb = dentry->d_sb; + struct inode *inode = dentry->d_inode; int error; error = inode_change_ok(inode, attr); diff -u --recursive --new-file v2.1.77/linux/fs/isofs/symlink.c linux/fs/isofs/symlink.c --- v2.1.77/linux/fs/isofs/symlink.c Mon Nov 17 18:47:21 1997 +++ linux/fs/isofs/symlink.c Sun Jan 4 00:53:41 1998 @@ -18,8 +18,8 @@ #include -static int isofs_readlink(struct inode *, char *, int); -static struct dentry * isofs_follow_link(struct inode * inode, struct dentry *base); +static int isofs_readlink(struct dentry *, char *, int); +static struct dentry * isofs_follow_link(struct dentry *, struct dentry *); /* * symlinks can't do much... @@ -44,14 +44,14 @@ NULL /* permission */ }; -static int isofs_readlink(struct inode * inode, char * buffer, int buflen) +static int isofs_readlink(struct dentry * dentry, char * buffer, int buflen) { char * pnt; int i; if (buflen > 1023) buflen = 1023; - pnt = get_rock_ridge_symlink(inode); + pnt = get_rock_ridge_symlink(dentry->d_inode); if (!pnt) return 0; @@ -65,12 +65,12 @@ return i; } -static struct dentry * isofs_follow_link(struct inode * inode, struct dentry *base) +static struct dentry * isofs_follow_link(struct dentry * dentry, + struct dentry *base) { char * pnt; - pnt = get_rock_ridge_symlink(inode); - + pnt = get_rock_ridge_symlink(dentry->d_inode); if(!pnt) { dput(base); return ERR_PTR(-ELOOP); diff -u --recursive --new-file v2.1.77/linux/fs/lockd/clntproc.c linux/fs/lockd/clntproc.c --- v2.1.77/linux/fs/lockd/clntproc.c Mon Dec 1 12:04:14 1997 +++ linux/fs/lockd/clntproc.c Sun Jan 4 00:53:43 1998 @@ -42,7 +42,7 @@ memset(argp, 0, sizeof(*argp)); argp->cookie = nlm_cookie++; argp->state = nsm_local_state; - lock->fh = *NFS_FH(fl->fl_file->f_dentry->d_inode); + lock->fh = *NFS_FH(fl->fl_file->f_dentry); lock->caller = system_utsname.nodename; lock->oh.data = req->a_owner; lock->oh.len = sprintf(req->a_owner, "%d@%s", diff -u --recursive --new-file v2.1.77/linux/fs/minix/symlink.c linux/fs/minix/symlink.c --- v2.1.77/linux/fs/minix/symlink.c Thu Jul 17 10:06:07 1997 +++ linux/fs/minix/symlink.c Sun Jan 4 00:53:41 1998 @@ -14,8 +14,8 @@ #include -static int minix_readlink(struct inode *, char *, int); -static struct dentry *minix_follow_link(struct inode *, struct dentry *); +static int minix_readlink(struct dentry *, char *, int); +static struct dentry *minix_follow_link(struct dentry *, struct dentry *); /* * symlinks can't do much... @@ -40,8 +40,10 @@ NULL /* permission */ }; -static struct dentry * minix_follow_link(struct inode * inode, struct dentry * base) +static struct dentry * minix_follow_link(struct dentry * dentry, + struct dentry * base) { + struct inode *inode = dentry->d_inode; struct buffer_head * bh; bh = minix_bread(inode, 0, 0); @@ -55,7 +57,7 @@ return base; } -static int minix_readlink(struct inode * inode, char * buffer, int buflen) +static int minix_readlink(struct dentry * dentry, char * buffer, int buflen) { struct buffer_head * bh; int i; @@ -63,7 +65,7 @@ if (buflen > 1023) buflen = 1023; - bh = minix_bread(inode, 0, 0); + bh = minix_bread(dentry->d_inode, 0, 0); if (!bh) return 0; i = 0; diff -u --recursive --new-file v2.1.77/linux/fs/namei.c linux/fs/namei.c --- v2.1.77/linux/fs/namei.c Sun Dec 21 22:36:16 1997 +++ linux/fs/namei.c Sun Jan 4 00:53:41 1998 @@ -221,33 +221,28 @@ } /* - * This is called when everything else fails, and we actually have - * to go to the low-level filesystem to find out what we should do.. - * - * We get the directory semaphore, and after getting that we also - * make sure that nobody added the entry to the dcache in the meantime.. + * "." and ".." are special - ".." especially so because it has to be able + * to know about the current root directory and parent relationships */ -static struct dentry * real_lookup(struct dentry * parent, struct qstr * name) +static struct dentry * reserved_lookup(struct dentry * parent, struct qstr * name) { - struct dentry * result; - struct inode *dir = parent->d_inode; + struct dentry *result = NULL; + if (name->name[0] == '.') { + switch (name->len) { + default: + break; + case 2: + if (name->name[1] != '.') + break; - down(&dir->i_sem); - result = d_lookup(parent, name); - if (!result) { - struct dentry * dentry = d_alloc(parent, name); - result = ERR_PTR(-ENOMEM); - if (dentry) { - int error = dir->i_op->lookup(dir, dentry); - result = dentry; - if (error) { - dput(dentry); - result = ERR_PTR(error); - } + if (parent != current->fs->root) + parent = parent->d_covers->d_parent; + /* fallthrough */ + case 1: + result = parent; } } - up(&dir->i_sem); - return result; + return dget(result); } /* @@ -274,28 +269,40 @@ } /* - * "." and ".." are special - ".." especially so because it has to be able - * to know about the current root directory and parent relationships + * This is called when everything else fails, and we actually have + * to go to the low-level filesystem to find out what we should do.. + * + * We get the directory semaphore, and after getting that we also + * make sure that nobody added the entry to the dcache in the meantime.. */ -static struct dentry * reserved_lookup(struct dentry * parent, struct qstr * name) +static struct dentry * real_lookup(struct dentry * parent, struct qstr * name) { - struct dentry *result = NULL; - if (name->name[0] == '.') { - switch (name->len) { - default: - break; - case 2: - if (name->name[1] != '.') - break; + struct dentry * result; + struct inode *dir = parent->d_inode; - if (parent != current->fs->root) - parent = parent->d_covers->d_parent; - /* fallthrough */ - case 1: - result = parent; + down(&dir->i_sem); + /* + * First re-do the cached lookup just in case it was created + * while we waited for the directory semaphore.. + * + * FIXME! This could use version numbering or similar to + * avoid unnecessary cache lookups. + */ + result = cached_lookup(parent, name); + if (!result) { + struct dentry * dentry = d_alloc(parent, name); + result = ERR_PTR(-ENOMEM); + if (dentry) { + int error = dir->i_op->lookup(dir, dentry); + result = dentry; + if (error) { + dput(dentry); + result = ERR_PTR(error); + } } } - return dget(result); + up(&dir->i_sem); + return result; } static struct dentry * do_follow_link(struct dentry *base, struct dentry *dentry) @@ -308,7 +315,7 @@ current->link_count++; /* This eats the base */ - result = inode->i_op->follow_link(inode, base); + result = inode->i_op->follow_link(dentry, base); current->link_count--; dput(dentry); return result; @@ -632,7 +639,7 @@ if (inode->i_sb && inode->i_sb->dq_op) inode->i_sb->dq_op->initialize(inode, -1); - error = do_truncate(inode, 0); + error = do_truncate(dentry, 0); } put_write_access(inode); if (error) @@ -1076,7 +1083,7 @@ if (dir->d_inode->i_sb && dir->d_inode->i_sb->dq_op) dir->d_inode->i_sb->dq_op->initialize(dir->d_inode, -1); - error = dir->d_inode->i_op->link(inode, dir->d_inode, new_dentry); + error = dir->d_inode->i_op->link(old_dentry, dir->d_inode, new_dentry); exit_lock: unlock_dir(dir); diff -u --recursive --new-file v2.1.77/linux/fs/ncpfs/dir.c linux/fs/ncpfs/dir.c --- v2.1.77/linux/fs/ncpfs/dir.c Mon Nov 17 18:47:21 1997 +++ linux/fs/ncpfs/dir.c Sun Jan 4 00:53:42 1998 @@ -105,10 +105,10 @@ /* * Dentry operations routines */ -static int ncp_lookup_validate(struct dentry *); -static void ncp_delete_dentry(struct dentry *); +static int ncp_lookup_validate(struct dentry *); static int ncp_hash_dentry(struct dentry *, struct qstr *); static int ncp_compare_dentry (struct dentry *, struct qstr *, struct qstr *); +static void ncp_delete_dentry(struct dentry *); static struct dentry_operations ncp_dentry_operations = { @@ -125,19 +125,23 @@ */ #define tolower(c) (((c) >= 'A' && (c) <= 'Z') ? (c)-('A'-'a') : (c)) - +/* + * Note: leave the hash unchanged if the directory + * is case-sensitive. + */ static int ncp_hash_dentry(struct dentry *dentry, struct qstr *this) { - unsigned long hash; - int i; + unsigned long hash; + int i; - hash = init_name_hash(); - for (i=0; ilen ; i++) - hash = partial_name_hash(tolower(this->name[i]),hash); - this->hash = end_name_hash(hash); - - return 0; + if (!ncp_case_sensitive(dentry->d_inode)) { + hash = init_name_hash(); + for (i=0; ilen ; i++) + hash = partial_name_hash(tolower(this->name[i]),hash); + this->hash = end_name_hash(hash); + } + return 0; } static int @@ -202,42 +206,14 @@ */ ino_t ncp_invent_inos(unsigned long n) { - static ino_t ino = 1; + static ino_t ino = 2; if (ino + 2*n < ino) { /* wrap around */ - ino += n; + ino = 2; } ino += n; - return ino; -} - -/* - * Check whether a dentry already exists for the given name, - * and return the inode number if it has an inode. This is - * needed to keep getcwd() working. - */ -static ino_t -find_inode_number(struct dentry *dir, struct qstr *name) -{ - unsigned long hash; - int i; - struct dentry * dentry; - ino_t ino = 0; - - hash = init_name_hash(); - for (i=0; ilen ; i++) - hash = partial_name_hash(tolower(name->name[i]),hash); - name->hash = end_name_hash(hash); - - dentry = d_lookup(dir, name); - if (dentry) - { - if (dentry->d_inode) - ino = dentry->d_inode->i_ino; - dput(dentry); - } return ino; } diff -u --recursive --new-file v2.1.77/linux/fs/ncpfs/file.c linux/fs/ncpfs/file.c --- v2.1.77/linux/fs/ncpfs/file.c Wed Nov 12 13:34:27 1997 +++ linux/fs/ncpfs/file.c Sun Jan 4 00:53:42 1998 @@ -15,11 +15,12 @@ #include #include #include -#include #include -#include "ncplib_kernel.h" #include +#include +#include "ncplib_kernel.h" + static inline int min(int a, int b) { return a < b ? a : b; @@ -65,7 +66,7 @@ result = ncp_open_create_file_or_subdir(NCP_SERVER(inode), NULL, NULL, OC_MODE_OPEN, 0, AR_READ, &finfo); - if (!result) { + if (result) { #ifdef NCPFS_PARANOIA printk(KERN_DEBUG "ncp_make_open: failed, result=%d\n", result); #endif @@ -82,11 +83,7 @@ #ifdef NCPFS_PARANOIA printk(KERN_DEBUG "ncp_make_open: file open, access=%x\n", access); #endif - if (((right == O_RDONLY) && ((access == O_RDONLY) - || (access == O_RDWR))) - || ((right == O_WRONLY) && ((access == O_WRONLY) - || (access == O_RDWR))) - || ((right == O_RDWR) && (access == O_RDWR))) + if (access == right || access == O_RDWR) error = 0; out_unlock: @@ -231,7 +228,7 @@ } } - inode->i_mtime = inode->i_ctime = CURRENT_TIME; + inode->i_mtime = inode->i_atime = CURRENT_TIME; file->f_pos = pos; diff -u --recursive --new-file v2.1.77/linux/fs/ncpfs/inode.c linux/fs/ncpfs/inode.c --- v2.1.77/linux/fs/ncpfs/inode.c Wed Nov 12 13:34:27 1997 +++ linux/fs/ncpfs/inode.c Sun Jan 4 00:53:42 1998 @@ -37,7 +37,7 @@ static void ncp_read_inode(struct inode *); static void ncp_put_inode(struct inode *); static void ncp_delete_inode(struct inode *); -static int ncp_notify_change(struct inode *, struct iattr *); +static int ncp_notify_change(struct dentry *, struct iattr *); static void ncp_put_super(struct super_block *); static int ncp_statfs(struct super_block *, struct statfs *, int); @@ -210,7 +210,7 @@ i->entryName[0] = '\0'; root->finfo.opened= 0; - info->ino = 1; + info->ino = 2; /* tradition */ info->nw_info = root->finfo; } @@ -354,7 +354,7 @@ ncp_unlock_server(server); close_fp(server->ncp_filp); - kill_proc(server->m.wdog_pid, SIGTERM, 0); + kill_proc(server->m.wdog_pid, SIGTERM, 1); ncp_kfree_s(server->packet, server->packet_size); @@ -387,30 +387,34 @@ return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0; } -static int ncp_notify_change(struct inode *inode, struct iattr *attr) +static int ncp_notify_change(struct dentry *dentry, struct iattr *attr) { + struct inode *inode = dentry->d_inode; int result = 0; int info_mask; struct nw_modify_dos_info info; - if (!ncp_conn_valid(NCP_SERVER(inode))) { - return -EIO; - } - if ((result = inode_change_ok(inode, attr)) < 0) - return result; + result = -EIO; + if (!ncp_conn_valid(NCP_SERVER(inode))) + goto out; + + result = inode_change_ok(inode, attr); + if (result < 0) + goto out; + result = -EPERM; if (((attr->ia_valid & ATTR_UID) && (attr->ia_uid != NCP_SERVER(inode)->m.uid))) - return -EPERM; + goto out; if (((attr->ia_valid & ATTR_GID) && (attr->ia_uid != NCP_SERVER(inode)->m.gid))) - return -EPERM; + goto out; if (((attr->ia_valid & ATTR_MODE) && (attr->ia_mode & ~(S_IFREG | S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO)))) - return -EPERM; + goto out; info_mask = 0; memset(&info, 0, sizeof(info)); @@ -455,7 +459,8 @@ if ((attr->ia_valid & ATTR_SIZE) != 0) { int written; - DPRINTK(KERN_DEBUG "ncpfs: trying to change size to %ld\n", attr->ia_size); + DPRINTK(KERN_DEBUG "ncpfs: trying to change size to %ld\n", + attr->ia_size); if ((result = ncp_make_open(inode, O_RDWR)) < 0) { return -EACCES; @@ -467,11 +472,8 @@ closing the file */ result = ncp_make_closed(inode); } - /* - * We need a dentry here ... - */ - /* ncp_invalid_dir_cache(NCP_INOP(inode)->dir->inode); */ - + ncp_invalid_dir_cache(dentry->d_parent->d_inode); +out: return result; } diff -u --recursive --new-file v2.1.77/linux/fs/nfs/dir.c linux/fs/nfs/dir.c --- v2.1.77/linux/fs/nfs/dir.c Fri Jan 2 14:37:02 1998 +++ linux/fs/nfs/dir.c Sun Jan 4 01:33:18 1998 @@ -64,7 +64,7 @@ static int nfs_rmdir(struct inode *, struct dentry *); static int nfs_unlink(struct inode *, struct dentry *); static int nfs_symlink(struct inode *, struct dentry *, const char *); -static int nfs_link(struct inode *, struct inode *, struct dentry *); +static int nfs_link(struct dentry *, struct inode *, struct dentry *); static int nfs_mknod(struct inode *, struct dentry *, int, int); static int nfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); @@ -108,8 +108,11 @@ static int nfs_dir_open(struct inode *dir, struct file *file) { - dfprintk(VFS, "NFS: nfs_dir_open(%x/%ld)\n", dir->i_dev, dir->i_ino); - return nfs_revalidate_inode(NFS_SERVER(dir), dir); + struct dentry *dentry = file->f_dentry; + + dfprintk(VFS, "NFS: nfs_dir_open(%s/%s)\n", + dentry->d_parent->d_name.name, dentry->d_name.name); + return nfs_revalidate_inode(NFS_DSERVER(dentry), dentry); } static ssize_t @@ -133,7 +136,8 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) { - struct inode *inode = filp->f_dentry->d_inode; + struct dentry *dentry = filp->f_dentry; + struct inode *inode = dentry->d_inode; static struct wait_queue *readdir_wait = NULL; struct wait_queue **waitp = NULL; struct nfs_dirent *cache, *free; @@ -144,14 +148,17 @@ __u32 *entry; char *name, *start; - dfprintk(VFS, "NFS: nfs_readdir(%x/%ld)\n", inode->i_dev, inode->i_ino); + dfprintk(VFS, "NFS: nfs_readdir(%s/%s)\n", + dentry->d_parent->d_name.name, dentry->d_name.name); + result = -EBADF; if (!inode || !S_ISDIR(inode->i_mode)) { printk("nfs_readdir: inode is NULL or not a directory\n"); - return -EBADF; + goto out; } - if ((result = nfs_revalidate_inode(NFS_SERVER(inode), inode)) < 0) - return result; + result = nfs_revalidate_inode(NFS_DSERVER(dentry), dentry); + if (result < 0) + goto out; /* * Try to find the entry in the cache @@ -250,7 +257,7 @@ goto done; } - result = nfs_proc_readdir(NFS_SERVER(inode), NFS_FH(inode), + result = nfs_proc_readdir(NFS_SERVER(inode), NFS_FH(dentry), cookie, PAGE_SIZE, cache->entry); if (result <= 0) goto done; @@ -300,6 +307,7 @@ wake_up(&cache->wait); wake_up(&readdir_wait); +out: return result; } @@ -449,11 +457,21 @@ #endif } -static struct dentry_operations nfs_dentry_operations = { +/* + * Called when the dentry is being freed to release private memory. + */ +static void nfs_dentry_release(struct dentry *dentry) +{ + if (dentry->d_fsdata) + kfree(dentry->d_fsdata); +} + +struct dentry_operations nfs_dentry_operations = { nfs_lookup_revalidate, /* d_validate(struct dentry *) */ - 0, /* d_hash */ - 0, /* d_compare */ - nfs_dentry_delete /* d_delete(struct dentry *) */ + NULL, /* d_hash */ + NULL, /* d_compare */ + nfs_dentry_delete, /* d_delete(struct dentry *) */ + nfs_dentry_release /* d_release(struct dentry *) */ }; /* @@ -470,16 +488,20 @@ } } +static void nfs_set_fh(struct dentry *dentry, struct nfs_fh *fhandle) +{ + *((struct nfs_fh *) dentry->d_fsdata) = *fhandle; +} + static int nfs_lookup(struct inode *dir, struct dentry * dentry) { - int len = dentry->d_name.len; struct inode *inode; int error; struct nfs_fh fhandle; struct nfs_fattr fattr; - dfprintk(VFS, "NFS: lookup(%x/%ld, %.*s)\n", - dir->i_dev, dir->i_ino, len, dentry->d_name.name); + dfprintk(VFS, "NFS: lookup(%s/%s)\n", + dentry->d_parent->d_name.name, dentry->d_name.name); if (!dir || !S_ISDIR(dir->i_mode)) { printk("nfs_lookup: inode is NULL or not a directory\n"); @@ -487,17 +509,26 @@ } error = -ENAMETOOLONG; - if (len > NFS_MAXNAMLEN) + if (dentry->d_name.len > NFS_MAXNAMLEN) goto out; - error = nfs_proc_lookup(NFS_SERVER(dir), NFS_FH(dir), + error = -ENOMEM; + if (!dentry->d_fsdata) { + dentry->d_fsdata = kmalloc(sizeof(struct nfs_fh), GFP_KERNEL); + if (!dentry->d_fsdata) + goto out; + } + dentry->d_op = &nfs_dentry_operations; + + error = nfs_proc_lookup(NFS_SERVER(dir), NFS_FH(dentry->d_parent), dentry->d_name.name, &fhandle, &fattr); inode = NULL; if (error == -ENOENT) goto no_entry; if (!error) { error = -EACCES; - inode = nfs_fhget(dir->i_sb, &fhandle, &fattr); + nfs_set_fh(dentry, &fhandle); + inode = nfs_fhget(dentry->d_sb, &fhandle, &fattr); if (inode) { #ifdef NFS_PARANOIA if (inode->i_count > (S_ISDIR(inode->i_mode) ? 1 : inode->i_nlink)) @@ -506,7 +537,6 @@ inode->i_ino, inode->i_count, inode->i_nlink); #endif no_entry: - dentry->d_op = &nfs_dentry_operations; d_add(dentry, inode); nfs_renew_times(dentry); error = 0; @@ -530,6 +560,7 @@ struct inode *inode; int error = -EACCES; + nfs_set_fh(dentry, fhandle); inode = nfs_fhget(dentry->d_sb, fhandle, fattr); if (inode) { #ifdef NFS_PARANOIA @@ -578,7 +609,7 @@ * Invalidate the dir cache before the operation to avoid a race. */ nfs_invalidate_dircache(dir); - error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dir), + error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dentry->d_parent), dentry->d_name.name, &sattr, &fhandle, &fattr); if (!error) error = nfs_instantiate(dentry, &fhandle, &fattr); @@ -616,7 +647,7 @@ sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1; nfs_invalidate_dircache(dir); - error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dir), + error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dentry->d_parent), dentry->d_name.name, &sattr, &fhandle, &fattr); if (!error) error = nfs_instantiate(dentry, &fhandle, &fattr); @@ -652,7 +683,7 @@ sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1; nfs_invalidate_dircache(dir); - error = nfs_proc_mkdir(NFS_SERVER(dir), NFS_FH(dir), + error = nfs_proc_mkdir(NFS_SERVER(dir), NFS_FH(dentry->d_parent), dentry->d_name.name, &sattr, &fhandle, &fattr); /* @@ -717,8 +748,8 @@ dentry->d_inode->i_nlink --; d_delete(dentry); nfs_invalidate_dircache(dir); - error = nfs_proc_rmdir(NFS_SERVER(dir), - NFS_FH(dir), dentry->d_name.name); + error = nfs_proc_rmdir(NFS_SERVER(dir), NFS_FH(dentry->d_parent), + dentry->d_name.name); if (!error) { if (rehash) d_add(dentry, NULL); @@ -839,8 +870,8 @@ nfs_invalidate_dircache(dir); error = nfs_proc_rename(NFS_SERVER(dir), - NFS_FH(dir), dentry->d_name.name, - NFS_FH(dir), silly); + NFS_FH(dentry->d_parent), dentry->d_name.name, + NFS_FH(dentry->d_parent), silly); if (!error) { nfs_renew_times(dentry); d_move(dentry, sdentry); @@ -914,8 +945,8 @@ d_delete(dentry); } nfs_invalidate_dircache(dir); - error = nfs_proc_remove(NFS_SERVER(dir), - NFS_FH(dir), dentry->d_name.name); + error = nfs_proc_remove(NFS_SERVER(dir), NFS_FH(dentry->d_parent), + dentry->d_name.name); /* * Rehash the negative dentry if the operation succeeded. */ @@ -998,7 +1029,7 @@ */ d_drop(dentry); nfs_invalidate_dircache(dir); - error = nfs_proc_symlink(NFS_SERVER(dir), NFS_FH(dir), + error = nfs_proc_symlink(NFS_SERVER(dir), NFS_FH(dentry->d_parent), dentry->d_name.name, symname, &sattr); if (!error) { nfs_renew_times(dentry->d_parent); @@ -1012,13 +1043,14 @@ } static int -nfs_link(struct inode *inode, struct inode *dir, struct dentry *dentry) +nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) { + struct inode *inode = old_dentry->d_inode; int error; - dfprintk(VFS, "NFS: link(%x/%ld -> %x/%ld, %s)\n", - inode->i_dev, inode->i_ino, - dir->i_dev, dir->i_ino, dentry->d_name.name); + dfprintk(VFS, "NFS: link(%s/%s -> %s/%s)\n", + old_dentry->d_parent->d_name.name, old_dentry->d_name.name, + dentry->d_parent->d_name.name, dentry->d_name.name); if (!dir || !S_ISDIR(dir->i_mode)) { printk("nfs_link: dir is NULL or not a directory\n"); @@ -1029,13 +1061,21 @@ if (dentry->d_name.len > NFS_MAXNAMLEN) goto out; + /* + * Drop the dentry in advance to force a new lookup. + * Since nfs_proc_link doesn't return a filehandle, + * we can't use the existing dentry. + */ + d_drop(dentry); nfs_invalidate_dircache(dir); - error = nfs_proc_link(NFS_SERVER(inode), NFS_FH(inode), NFS_FH(dir), - dentry->d_name.name); + error = nfs_proc_link(NFS_DSERVER(old_dentry), NFS_FH(old_dentry), + NFS_FH(dentry->d_parent), dentry->d_name.name); if (!error) { - inode->i_count ++; - inode->i_nlink ++; /* no need to wait for nfs_refresh_inode() */ - d_instantiate(dentry, inode); + /* + * Update the link count immediately, as some apps + * (e.g. pine) test this after making a link. + */ + inode->i_nlink++; } out: return error; @@ -1181,9 +1221,9 @@ nfs_invalidate_dircache(new_dir); nfs_invalidate_dircache(old_dir); - error = nfs_proc_rename(NFS_SERVER(old_dir), - NFS_FH(old_dir), old_dentry->d_name.name, - NFS_FH(new_dir), new_dentry->d_name.name); + error = nfs_proc_rename(NFS_DSERVER(old_dentry), + NFS_FH(old_dentry->d_parent), old_dentry->d_name.name, + NFS_FH(new_dentry->d_parent), new_dentry->d_name.name); if (!error) { /* Update the dcache if needed */ if (rehash) diff -u --recursive --new-file v2.1.77/linux/fs/nfs/file.c linux/fs/nfs/file.c --- v2.1.77/linux/fs/nfs/file.c Thu Dec 4 14:53:56 1997 +++ linux/fs/nfs/file.c Sun Jan 4 00:53:41 1998 @@ -109,15 +109,14 @@ static ssize_t nfs_file_read(struct file * file, char * buf, size_t count, loff_t *ppos) { - struct inode * inode = file->f_dentry->d_inode; + struct dentry * dentry = file->f_dentry; ssize_t result; - dfprintk(VFS, "nfs: read(%x/%ld, %lu@%lu)\n", - inode->i_dev, inode->i_ino, - (unsigned long) count, - (unsigned long) *ppos); + dfprintk(VFS, "nfs: read(%s/%s, %lu@%lu)\n", + dentry->d_parent->d_name.name, dentry->d_name.name, + (unsigned long) count, (unsigned long) *ppos); - result = nfs_revalidate_inode(NFS_SERVER(inode), inode); + result = nfs_revalidate_inode(NFS_DSERVER(dentry), dentry); if (!result) result = generic_file_read(file, buf, count, ppos); return result; @@ -126,12 +125,13 @@ static int nfs_file_mmap(struct file * file, struct vm_area_struct * vma) { - struct inode *inode = file->f_dentry->d_inode; + struct dentry *dentry = file->f_dentry; int status; - dfprintk(VFS, "nfs: mmap(%x/%ld)\n", inode->i_dev, inode->i_ino); + dfprintk(VFS, "nfs: mmap(%s/%s)\n", + dentry->d_parent->d_name.name, dentry->d_name.name); - status = nfs_revalidate_inode(NFS_SERVER(inode), inode); + status = nfs_revalidate_inode(NFS_DSERVER(dentry), dentry); if (!status) status = generic_file_mmap(file, vma); return status; @@ -163,31 +163,33 @@ static ssize_t nfs_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { - struct inode * inode = file->f_dentry->d_inode; + struct dentry * dentry = file->f_dentry; + struct inode * inode = dentry->d_inode; ssize_t result; - dfprintk(VFS, "nfs: write(%x/%ld (%d), %lu@%lu)\n", - inode->i_dev, inode->i_ino, inode->i_count, - (unsigned long) count, (unsigned long) *ppos); + dfprintk(VFS, "nfs: write(%s/%s (%d), %lu@%lu)\n", + dentry->d_parent->d_name.name, dentry->d_name.name, + inode->i_count, (unsigned long) count, (unsigned long) *ppos); if (!inode) { printk("nfs_file_write: inode = NULL\n"); return -EINVAL; } - if (IS_SWAPFILE(inode)) { - printk("NFS: attempt to write to active swap file!\n"); - return -EBUSY; - } - result = nfs_revalidate_inode(NFS_SERVER(inode), inode); + result = -EBUSY; + if (IS_SWAPFILE(inode)) + goto out_swapfile; + result = nfs_revalidate_inode(NFS_DSERVER(dentry), dentry); if (result) goto out; - /* N.B. This should be impossible now -- inodes can't change mode */ - if (!S_ISREG(inode->i_mode)) { - printk("nfs_file_write: write to non-file, mode %07o\n", - inode->i_mode); - return -EINVAL; - } +#ifdef NFS_PARANOIA +/* N.B. This should be impossible now -- inodes can't change mode */ +if (!S_ISREG(inode->i_mode)) { + printk("nfs_file_write: write to non-file, mode %07o\n", + inode->i_mode); + return -EINVAL; +} +#endif result = count; if (!count) goto out; @@ -198,6 +200,10 @@ result = generic_file_write(file, buf, count, ppos); out: return result; + +out_swapfile: + printk("NFS: attempt to write to active swap file!\n"); + goto out; } /* diff -u --recursive --new-file v2.1.77/linux/fs/nfs/inode.c linux/fs/nfs/inode.c --- v2.1.77/linux/fs/nfs/inode.c Sun Dec 21 22:36:16 1997 +++ linux/fs/nfs/inode.c Sun Jan 4 00:53:41 1998 @@ -38,7 +38,7 @@ static void nfs_read_inode(struct inode *); static void nfs_put_inode(struct inode *); static void nfs_delete_inode(struct inode *); -static int nfs_notify_change(struct inode *, struct iattr *); +static int nfs_notify_change(struct dentry *, struct iattr *); static void nfs_put_super(struct super_block *); static int nfs_statfs(struct super_block *, struct statfs *, int); @@ -180,15 +180,15 @@ nfs_read_super(struct super_block *sb, void *raw_data, int silent) { struct nfs_mount_data *data = (struct nfs_mount_data *) raw_data; - struct sockaddr_in srvaddr; struct nfs_server *server; - struct rpc_timeout timeparms; struct rpc_xprt *xprt; struct rpc_clnt *clnt; + struct nfs_fh *root_fh; + struct inode *root_inode; unsigned int authflavor; int tcp; - kdev_t dev = sb->s_dev; - struct inode *root_inode; + struct sockaddr_in srvaddr; + struct rpc_timeout timeparms; MOD_INC_USE_COUNT; if (!data) @@ -211,7 +211,6 @@ lock_super(sb); sb->s_magic = NFS_SUPER_MAGIC; - sb->s_dev = dev; sb->s_op = &nfs_sops; sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits); sb->u.nfs_sb.s_root = data->root; @@ -234,21 +233,19 @@ timeparms.to_maxval = tcp? RPC_MAX_TCP_TIMEOUT : RPC_MAX_UDP_TIMEOUT; timeparms.to_exponential = 1; - /* Choose authentication flavor */ - if (data->flags & NFS_MOUNT_SECURE) { - authflavor = RPC_AUTH_DES; - } else if (data->flags & NFS_MOUNT_KERBEROS) { - authflavor = RPC_AUTH_KRB; - } else { - authflavor = RPC_AUTH_UNIX; - } - /* Now create transport and client */ xprt = xprt_create_proto(tcp? IPPROTO_TCP : IPPROTO_UDP, &srvaddr, &timeparms); if (xprt == NULL) goto out_no_xprt; + /* Choose authentication flavor */ + authflavor = RPC_AUTH_UNIX; + if (data->flags & NFS_MOUNT_SECURE) + authflavor = RPC_AUTH_DES; + else if (data->flags & NFS_MOUNT_KERBEROS) + authflavor = RPC_AUTH_KRB; + clnt = rpc_create_client(xprt, server->hostname, &nfs_program, NFS_VERSION, authflavor); if (clnt == NULL) @@ -267,12 +264,20 @@ * Keep the super block locked while we try to get * the root fh attributes. */ + root_fh = kmalloc(sizeof(struct nfs_fh), GFP_KERNEL); + if (!root_fh) + goto out_no_fh; + *root_fh = data->root; + root_inode = nfs_fhget(sb, &data->root, NULL); if (!root_inode) goto out_no_root; sb->s_root = d_alloc_root(root_inode, NULL); if (!sb->s_root) goto out_no_root; + sb->s_root->d_op = &nfs_dentry_operations; + sb->s_root->d_fsdata = root_fh; + /* We're airborne */ unlock_super(sb); @@ -285,6 +290,8 @@ out_no_root: printk("nfs_read_super: get root inode failed\n"); iput(root_inode); + kfree(root_fh); +out_no_fh: rpciod_down(); goto out_shutdown; @@ -352,36 +359,28 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fhandle, struct nfs_fattr *fattr) { - struct nfs_fattr newfattr; int error; - struct inode *inode; + struct inode *inode = NULL; + struct nfs_fattr newfattr; - if (!sb) { - printk("nfs_fhget: super block is NULL\n"); - return NULL; - } + if (!sb) + goto out_bad_args; if (!fattr) { - error = nfs_proc_getattr(&sb->u.nfs_sb.s_server, fhandle, - &newfattr); - if (error) { - printk("nfs_fhget: getattr error = %d\n", -error); - return NULL; - } fattr = &newfattr; - } - if (!(inode = iget(sb, fattr->fileid))) { - printk("nfs_fhget: iget failed\n"); - return NULL; - } + error = nfs_proc_getattr(&sb->u.nfs_sb.s_server, fhandle,fattr); + if (error) + goto out_bad_attr; + } + inode = iget(sb, fattr->fileid); + if (!inode) + goto out_no_inode; #ifdef NFS_PARANOIA if (inode->i_dev != sb->s_dev) printk("nfs_fhget: impossible\n"); #endif - if (inode->i_ino != fattr->fileid) { - printk("nfs_fhget: unexpected inode from iget\n"); - return inode; - } + if (inode->i_ino != fattr->fileid) + goto out_bad_id; /* * Check whether the mode has been set, as we only want to @@ -412,29 +411,41 @@ inode->i_size = fattr->size; inode->i_mtime = fattr->mtime.seconds; NFS_OLDMTIME(inode) = fattr->mtime.seconds; - *NFS_FH(inode) = *fhandle; } - if (memcmp(NFS_FH(inode), fhandle, sizeof(struct nfs_fh))) - printk("nfs_fhget: fhandle changed!\n"); nfs_refresh_inode(inode, fattr); dprintk("NFS: fhget(%x/%ld ct=%d)\n", inode->i_dev, inode->i_ino, inode->i_count); +out: return inode; + +out_bad_args: + printk("nfs_fhget: super block is NULL\n"); + goto out; +out_bad_attr: + printk("nfs_fhget: getattr error = %d\n", -error); + goto out; +out_no_inode: + printk("nfs_fhget: iget failed\n"); + goto out; +out_bad_id: + printk("nfs_fhget: unexpected inode from iget\n"); + goto out; } int -nfs_notify_change(struct inode *inode, struct iattr *attr) +nfs_notify_change(struct dentry *dentry, struct iattr *attr) { + struct inode *inode = dentry->d_inode; + int error; struct nfs_sattr sattr; struct nfs_fattr fattr; - int error; /* * Make sure the inode is up-to-date. */ - error = nfs_revalidate(inode); + error = nfs_revalidate(dentry); if (error) { #ifdef NFS_PARANOIA printk("nfs_notify_change: revalidate failed, error=%d\n", error); @@ -470,7 +481,7 @@ sattr.atime.useconds = 0; } - error = nfs_proc_setattr(NFS_SERVER(inode), NFS_FH(inode), + error = nfs_proc_setattr(NFS_DSERVER(dentry), NFS_FH(dentry), &sattr, &fattr); if (error) goto out; @@ -497,9 +508,9 @@ * Externally visible revalidation function */ int -nfs_revalidate(struct inode *inode) +nfs_revalidate(struct dentry *dentry) { - return nfs_revalidate_inode(NFS_SERVER(inode), inode); + return nfs_revalidate_inode(NFS_DSERVER(dentry), dentry); } /* @@ -507,38 +518,43 @@ * the cached attributes have to be refreshed. */ int -_nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) +_nfs_revalidate_inode(struct nfs_server *server, struct dentry *dentry) { - struct nfs_fattr fattr; + struct inode *inode = dentry->d_inode; int status = 0; + struct nfs_fattr fattr; if (jiffies - NFS_READTIME(inode) < NFS_ATTRTIMEO(inode)) goto out; - dfprintk(PAGECACHE, "NFS: revalidating %x/%ld inode\n", - inode->i_dev, inode->i_ino); - status = nfs_proc_getattr(server, NFS_FH(inode), &fattr); + dfprintk(PAGECACHE, "NFS: revalidating %s/%s, ino=%ld\n", + dentry->d_parent->d_name.name, dentry->d_name.name, + inode->i_ino); + status = nfs_proc_getattr(server, NFS_FH(dentry), &fattr); if (status) { #ifdef NFS_PARANOIA -printk("nfs_revalidate_inode: getattr failed, error=%d\n", status); +printk("nfs_revalidate_inode: %s/%s getattr failed, ino=%ld, error=%d\n", +dentry->d_parent->d_name.name, dentry->d_name.name, inode->i_ino, status); #endif - goto done; + goto out; } status = nfs_refresh_inode(inode, &fattr); - if (status) - goto done; + if (status) { +#ifdef NFS_PARANOIA +printk("nfs_revalidate_inode: %s/%s refresh failed, ino=%ld, error=%d\n", +dentry->d_parent->d_name.name, dentry->d_name.name, inode->i_ino, status); +#endif + goto out; + } if (fattr.mtime.seconds == NFS_OLDMTIME(inode)) { /* Update attrtimeo value */ if ((NFS_ATTRTIMEO(inode) <<= 1) > NFS_MAXATTRTIMEO(inode)) NFS_ATTRTIMEO(inode) = NFS_MAXATTRTIMEO(inode); } NFS_OLDMTIME(inode) = fattr.mtime.seconds; - -done: - dfprintk(PAGECACHE, - "NFS: inode %x/%ld revalidation complete (status %d).\n", - inode->i_dev, inode->i_ino, status); + dfprintk(PAGECACHE, "NFS: %s/%s revalidation complete\n", + dentry->d_parent->d_name.name, dentry->d_name.name); out: return status; } @@ -569,7 +585,8 @@ goto out; } if (inode->i_ino != fattr->fileid) { - printk("nfs_refresh_inode: inode number mismatch\n"); + printk("nfs_refresh_inode: mismatch, ino=%ld, fattr=%d\n", + inode->i_ino, fattr->fileid); goto out; } diff -u --recursive --new-file v2.1.77/linux/fs/nfs/read.c linux/fs/nfs/read.c --- v2.1.77/linux/fs/nfs/read.c Thu Jul 17 10:06:07 1997 +++ linux/fs/nfs/read.c Sun Jan 4 00:53:41 1998 @@ -65,8 +65,8 @@ /* * Read a page synchronously. */ -int -nfs_readpage_sync(struct inode *inode, struct page *page) +static int +nfs_readpage_sync(struct dentry *dentry, struct inode *inode, struct page *page) { struct nfs_rreq rqst; unsigned long offset = page->offset; @@ -83,12 +83,13 @@ if (count < rsize) rsize = count; - dprintk("NFS: nfs_proc_read(%s, (%x,%lx), %ld, %d, %p)\n", - NFS_SERVER(inode)->hostname, inode->i_dev, - inode->i_ino, offset, rsize, buffer); + dprintk("NFS: nfs_proc_read(%s, (%s/%s), %ld, %d, %p)\n", + NFS_SERVER(inode)->hostname, + dentry->d_parent->d_name.name, dentry->d_name.name, + offset, rsize, buffer); /* Set up arguments and perform rpc call */ - nfs_readreq_setup(&rqst, NFS_FH(inode), offset, buffer, rsize); + nfs_readreq_setup(&rqst, NFS_FH(dentry), offset, buffer, rsize); result = rpc_call(NFS_CLIENT(inode), NFSPROC_READ, &rqst.ra_args, &rqst.ra_res, flags); @@ -160,7 +161,8 @@ } static inline int -nfs_readpage_async(struct inode *inode, struct page *page) +nfs_readpage_async(struct dentry *dentry, struct inode *inode, + struct page *page) { struct nfs_rreq *req; int result, flags; @@ -175,7 +177,7 @@ } /* Initialize request */ - nfs_readreq_setup(req, NFS_FH(inode), page->offset, + nfs_readreq_setup(req, NFS_FH(dentry), page->offset, (void *) page_address(page), PAGE_SIZE); req->ra_inode = inode; req->ra_page = page; @@ -209,8 +211,9 @@ * - The server is congested. */ int -nfs_readpage(struct inode *inode, struct page *page) +nfs_readpage(struct dentry *dentry, struct page *page) { + struct inode *inode = dentry->d_inode; unsigned long address; int error = -1; @@ -218,11 +221,11 @@ set_bit(PG_locked, &page->flags); address = page_address(page); atomic_inc(&page->count); - if (!IS_SWAPFILE(inode) && !PageError(page) - && NFS_SERVER(inode)->rsize >= PAGE_SIZE) - error = nfs_readpage_async(inode, page); + if (!IS_SWAPFILE(inode) && !PageError(page) && + NFS_SERVER(inode)->rsize >= PAGE_SIZE) + error = nfs_readpage_async(dentry, inode, page); if (error < 0) /* couldn't enqueue */ - error = nfs_readpage_sync(inode, page); + error = nfs_readpage_sync(dentry, inode, page); if (error < 0 && IS_SWAPFILE(inode)) printk("Aiee.. nfs swap-in of page failed!\n"); free_page(address); diff -u --recursive --new-file v2.1.77/linux/fs/nfs/symlink.c linux/fs/nfs/symlink.c --- v2.1.77/linux/fs/nfs/symlink.c Mon Aug 18 18:19:46 1997 +++ linux/fs/nfs/symlink.c Sun Jan 4 00:53:41 1998 @@ -18,8 +18,8 @@ #include -static int nfs_readlink(struct inode *, char *, int); -static struct dentry *nfs_follow_link(struct inode *, struct dentry *); +static int nfs_readlink(struct dentry *, char *, int); +static struct dentry *nfs_follow_link(struct dentry *, struct dentry *); /* * symlinks can't do much... @@ -44,19 +44,20 @@ NULL /* permission */ }; -static int nfs_readlink(struct inode *inode, char *buffer, int buflen) +static int nfs_readlink(struct dentry *dentry, char *buffer, int buflen) { int error; unsigned int len; char *res; void *mem; - dfprintk(VFS, "nfs: readlink(%x/%ld)\n", inode->i_dev, inode->i_ino); + dfprintk(VFS, "nfs: readlink(%s/%s)\n", + dentry->d_parent->d_name.name, dentry->d_name.name); if (buflen > NFS_MAXPATHLEN) buflen = NFS_MAXPATHLEN; - error = nfs_proc_readlink(NFS_SERVER(inode), NFS_FH(inode), &mem, - &res, &len, buflen); + error = nfs_proc_readlink(NFS_DSERVER(dentry), NFS_FH(dentry), + &mem, &res, &len, buflen); if (! error) { copy_to_user(buffer, res, len); put_user('\0', buffer + len); @@ -66,34 +67,41 @@ return error; } -static struct dentry * nfs_follow_link(struct inode * inode, struct dentry *base) +static struct dentry * +nfs_follow_link(struct dentry * dentry, struct dentry *base) { int error; unsigned int len; char *res; void *mem; char *path; + struct dentry *result; - dfprintk(VFS, "nfs: follow_link(%x/%ld)\n", inode->i_dev, inode->i_ino); + dfprintk(VFS, "nfs: follow_link(%s/%s)\n", + dentry->d_parent->d_name.name, dentry->d_name.name); - error = nfs_proc_readlink(NFS_SERVER(inode), NFS_FH(inode), &mem, - &res, &len, NFS_MAXPATHLEN); + error = nfs_proc_readlink(NFS_DSERVER(dentry), NFS_FH(dentry), + &mem, &res, &len, NFS_MAXPATHLEN); + result = ERR_PTR(error); + if (error) + goto out_dput; - if (error) { - dput(base); - return ERR_PTR(error); - } + result = ERR_PTR(-ENOMEM); path = kmalloc(len + 1, GFP_KERNEL); - if (!path) { - dput(base); - kfree(mem); - return ERR_PTR(-ENOMEM); - } + if (!path) + goto out_mem; memcpy(path, res, len); path[len] = 0; kfree(mem); - base = lookup_dentry(path, base, 1); + result = lookup_dentry(path, base, 1); kfree(path); - return base; +out: + return result; + +out_mem: + kfree(mem); +out_dput: + dput(base); + goto out; } diff -u --recursive --new-file v2.1.77/linux/fs/nfs/write.c linux/fs/nfs/write.c --- v2.1.77/linux/fs/nfs/write.c Sun Dec 21 22:36:16 1997 +++ linux/fs/nfs/write.c Sun Jan 4 00:53:41 1998 @@ -79,6 +79,7 @@ struct nfs_wreq { struct rpc_listitem wb_list; /* linked list of req's */ struct rpc_task wb_task; /* RPC task */ + struct dentry * wb_dentry; /* dentry referenced */ struct inode * wb_inode; /* inode referenced */ struct page * wb_page; /* page to be written */ unsigned int wb_offset; /* offset within page */ @@ -169,17 +170,17 @@ * Offset is the data offset within the page. */ static int -nfs_writepage_sync(struct inode *inode, struct page *page, - unsigned long offset, unsigned int count) +nfs_writepage_sync(struct dentry *dentry, struct inode *inode, + struct page *page, unsigned long offset, unsigned int count) { - struct nfs_fattr fattr; unsigned int wsize = NFS_SERVER(inode)->wsize; int result, refresh = 0, written = 0; u8 *buffer; + struct nfs_fattr fattr; - dprintk("NFS: nfs_writepage_sync(%x/%ld %d@%ld)\n", - inode->i_dev, inode->i_ino, - count, page->offset + offset); + dprintk("NFS: nfs_writepage_sync(%s/%s %d@%ld)\n", + dentry->d_parent->d_name.name, dentry->d_name.name, + count, page->offset + offset); buffer = (u8 *) page_address(page) + offset; offset += page->offset; @@ -188,7 +189,7 @@ if (count < wsize && !IS_SWAPFILE(inode)) wsize = count; - result = nfs_proc_write(NFS_SERVER(inode), NFS_FH(inode), + result = nfs_proc_write(NFS_DSERVER(dentry), NFS_FH(dentry), IS_SWAPFILE(inode), offset, wsize, buffer, &fattr); @@ -380,16 +381,16 @@ * Create and initialize a writeback request */ static inline struct nfs_wreq * -create_write_request(struct inode *inode, struct page *page, - unsigned int offset, unsigned int bytes) +create_write_request(struct dentry *dentry, struct inode *inode, + struct page *page, unsigned int offset, unsigned int bytes) { struct nfs_wreq *wreq; struct rpc_clnt *clnt = NFS_CLIENT(inode); struct rpc_task *task; - dprintk("NFS: create_write_request(%x/%ld, %ld+%d)\n", - inode->i_dev, inode->i_ino, - page->offset + offset, bytes); + dprintk("NFS: create_write_request(%s/%s, %ld+%d)\n", + dentry->d_parent->d_name.name, dentry->d_name.name, + page->offset + offset, bytes); /* FIXME: Enforce hard limit on number of concurrent writes? */ @@ -408,6 +409,7 @@ goto out_req; /* Put the task on inode's writeback request list. */ + wreq->wb_dentry = dentry; wreq->wb_inode = inode; wreq->wb_pid = current->pid; wreq->wb_page = page; @@ -504,9 +506,9 @@ * (for now), and we currently do this synchronously only. */ int -nfs_writepage(struct inode *inode, struct page *page) +nfs_writepage(struct dentry *dentry, struct page *page) { - return nfs_writepage_sync(inode, page, 0, PAGE_SIZE); + return nfs_writepage_sync(dentry, dentry->d_inode, page, 0, PAGE_SIZE); } /* @@ -516,16 +518,17 @@ * things with a page scheduled for an RPC call (e.g. invalidate it). */ int -nfs_updatepage(struct inode *inode, struct page *page, const char *buffer, +nfs_updatepage(struct dentry *dentry, struct page *page, const char *buffer, unsigned long offset, unsigned int count, int sync) { + struct inode *inode = dentry->d_inode; struct nfs_wreq *req; int status = 0, page_locked = 1; u8 *page_addr; - dprintk("NFS: nfs_updatepage(%x/%ld %d@%ld, sync=%d)\n", - inode->i_dev, inode->i_ino, - count, page->offset+offset, sync); + dprintk("NFS: nfs_updatepage(%s/%s %d@%ld, sync=%d)\n", + dentry->d_parent->d_name.name, dentry->d_name.name, + count, page->offset+offset, sync); set_bit(PG_locked, &page->flags); page_addr = (u8 *) page_address(page); @@ -535,7 +538,7 @@ */ if (NFS_SERVER(inode)->wsize < PAGE_SIZE) { copy_from_user(page_addr + offset, buffer, count); - return nfs_writepage_sync(inode, page, offset, count); + return nfs_writepage_sync(dentry, inode, page, offset, count); } /* @@ -560,7 +563,7 @@ /* Create the write request. */ status = -ENOBUFS; - req = create_write_request(inode, page, offset, count); + req = create_write_request(dentry, inode, page, offset, count); if (!req) goto done; @@ -823,7 +826,7 @@ { struct nfs_wreq *req = (struct nfs_wreq *) task->tk_calldata; struct page *page = req->wb_page; - struct inode *inode = req->wb_inode; + struct dentry *dentry = req->wb_dentry; dprintk("NFS: %4d nfs_wback_lock (status %d flags %x)\n", task->tk_pid, task->tk_status, req->wb_flags); @@ -856,7 +859,7 @@ } /* Setup the task struct for a writeback call */ - req->wb_args->fh = NFS_FH(inode); + req->wb_args->fh = NFS_FH(dentry); req->wb_args->offset = page->offset + req->wb_offset; req->wb_args->count = req->wb_bytes; req->wb_args->buffer = (void *) (page_address(page) + req->wb_offset); @@ -873,16 +876,12 @@ nfs_wback_result(struct rpc_task *task) { struct nfs_wreq *req = (struct nfs_wreq *) task->tk_calldata; - struct inode *inode; - struct page *page; - int status; + struct inode *inode = req->wb_inode; + struct page *page = req->wb_page; + int status = task->tk_status; dprintk("NFS: %4d nfs_wback_result (status %d)\n", - task->tk_pid, task->tk_status); - - inode = req->wb_inode; - page = req->wb_page; - status = task->tk_status; + task->tk_pid, status); if (status < 0) { /* diff -u --recursive --new-file v2.1.77/linux/fs/nfsd/vfs.c linux/fs/nfsd/vfs.c --- v2.1.77/linux/fs/nfsd/vfs.c Tue Dec 23 16:31:00 1997 +++ linux/fs/nfsd/vfs.c Sun Jan 4 00:53:43 1998 @@ -230,7 +230,7 @@ if (iap->ia_valid) { iap->ia_valid |= ATTR_CTIME; iap->ia_ctime = CURRENT_TIME; - err = notify_change(inode, iap); + err = notify_change(dentry, iap); if (err) return nfserrno(-err); if (EX_ISSYNC(fhp->fh_export)) @@ -475,7 +475,7 @@ ia.ia_valid = ATTR_MODE; ia.ia_mode = inode->i_mode & ~(S_ISUID | S_ISGID); - notify_change(inode, &ia); + notify_change(dentry, &ia); } fh_unlock(fhp); /* unlock inode */ @@ -668,7 +668,7 @@ fh_lock(fhp); newattrs.ia_size = size; newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; - err = notify_change(inode, &newattrs); + err = notify_change(dentry, &newattrs); if (!err) { vmtruncate(inode, size); if (inode->i_op && inode->i_op->truncate) @@ -710,7 +710,7 @@ UPDATE_ATIME(inode); /* N.B. Why does this call need a get_fs()?? */ oldfs = get_fs(); set_fs(KERNEL_DS); - err = inode->i_op->readlink(inode, buf, *lenp); + err = inode->i_op->readlink(dentry, buf, *lenp); set_fs(oldfs); if (err < 0) @@ -789,7 +789,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int len, struct svc_fh *tfhp) { - struct dentry *ddir, *dnew; + struct dentry *ddir, *dnew, *dold; struct inode *dirp, *dest; int err; @@ -811,12 +811,14 @@ err = -EEXIST; if (dnew->d_inode) goto dput_and_out; - dest = tfhp->fh_dentry->d_inode; err = -EPERM; if (!len) goto dput_and_out; + dold = tfhp->fh_dentry; + dest = dold->d_inode; + err = -EACCES; if (nfsd_iscovered(ddir, ffhp->fh_export)) goto dput_and_out; @@ -830,7 +832,7 @@ goto dput_and_out; fh_lock(ffhp); - err = dirp->i_op->link(dest, dirp, dnew); + err = dirp->i_op->link(dold, dirp, dnew); fh_unlock(ffhp); if (!err && EX_ISSYNC(ffhp->fh_export)) { diff -u --recursive --new-file v2.1.77/linux/fs/open.c linux/fs/open.c --- v2.1.77/linux/fs/open.c Tue Sep 23 16:48:49 1997 +++ linux/fs/open.c Sun Jan 4 00:53:41 1998 @@ -69,15 +69,16 @@ return error; } -int do_truncate(struct inode *inode, unsigned long length) +int do_truncate(struct dentry *dentry, unsigned long length) { + struct inode *inode = dentry->d_inode; int error; struct iattr newattrs; down(&inode->i_sem); newattrs.ia_size = length; newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; - error = notify_change(inode, &newattrs); + error = notify_change(dentry, &newattrs); if (!error) { /* truncate virtual mappings of this file */ vmtruncate(inode, length); @@ -128,7 +129,7 @@ if (!error) { if (inode->i_sb && inode->i_sb->dq_op) inode->i_sb->dq_op->initialize(inode, -1); - error = do_truncate(inode, length); + error = do_truncate(dentry, length); } put_write_access(inode); dput_and_out: @@ -161,7 +162,7 @@ lengthi_size ? length : inode->i_size, abs(inode->i_size - length)); if (!error) - error = do_truncate(inode, length); + error = do_truncate(dentry, length); } unlock_kernel(); return error; @@ -214,7 +215,7 @@ (error = permission(inode,MAY_WRITE)) != 0) goto dput_and_out; } - error = notify_change(inode, &newattrs); + error = notify_change(dentry, &newattrs); dput_and_out: dput(dentry); out: @@ -261,7 +262,7 @@ if ((error = permission(inode,MAY_WRITE)) != 0) goto dput_and_out; } - error = notify_change(inode, &newattrs); + error = notify_change(dentry, &newattrs); dput_and_out: dput(dentry); out: @@ -441,7 +442,7 @@ mode = inode->i_mode; newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; - err = notify_change(inode, &newattrs); + err = notify_change(dentry, &newattrs); out: unlock_kernel(); return err; @@ -474,7 +475,7 @@ mode = inode->i_mode; newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; - error = notify_change(inode, &newattrs); + error = notify_change(dentry, &newattrs); dput_and_out: dput(dentry); @@ -530,11 +531,11 @@ error = -EDQUOT; if (inode->i_sb->dq_op->transfer(inode, &newattrs, 0)) goto out; - error = notify_change(inode, &newattrs); + error = notify_change(dentry, &newattrs); if (error) inode->i_sb->dq_op->transfer(inode, &newattrs, 1); } else - error = notify_change(inode, &newattrs); + error = notify_change(dentry, &newattrs); out: return error; } diff -u --recursive --new-file v2.1.77/linux/fs/proc/link.c linux/fs/proc/link.c --- v2.1.77/linux/fs/proc/link.c Mon Aug 4 16:25:39 1997 +++ linux/fs/proc/link.c Sun Jan 4 00:53:41 1998 @@ -15,8 +15,8 @@ #include #include -static int proc_readlink(struct inode *, char *, int); -static struct dentry * proc_follow_link(struct inode *, struct dentry *); +static int proc_readlink(struct dentry *, char *, int); +static struct dentry * proc_follow_link(struct dentry *, struct dentry *); /* * PLAN9_SEMANTICS won't work any more: it used an ugly hack that broke @@ -60,8 +60,10 @@ NULL /* permission */ }; -static struct dentry * proc_follow_link(struct inode *inode, struct dentry *base) +static struct dentry * proc_follow_link(struct dentry *dentry, + struct dentry *base) { + struct inode *inode = dentry->d_inode; struct task_struct *p; struct dentry * result; int ino, pid; @@ -73,7 +75,7 @@ error = permission(inode, MAY_EXEC); result = ERR_PTR(error); if (error) - return result; + goto out; ino = inode->i_ino; pid = ino >> 16; @@ -82,7 +84,7 @@ p = find_task_by_pid(pid); result = ERR_PTR(-ENOENT); if (!p) - return result; + goto out; switch (ino) { case PROC_PID_CWD: @@ -126,14 +128,15 @@ break; } } +out: return result; } -static int proc_readlink(struct inode * inode, char * buffer, int buflen) +static int proc_readlink(struct dentry * dentry, char * buffer, int buflen) { int error; - struct dentry * dentry = proc_follow_link(inode, NULL); + dentry = proc_follow_link(dentry, NULL); error = PTR_ERR(dentry); if (!IS_ERR(dentry)) { error = -ENOENT; diff -u --recursive --new-file v2.1.77/linux/fs/proc/proc_devtree.c linux/fs/proc/proc_devtree.c --- v2.1.77/linux/fs/proc/proc_devtree.c Mon Aug 18 18:19:46 1997 +++ linux/fs/proc/proc_devtree.c Sun Jan 4 00:53:41 1998 @@ -65,24 +65,24 @@ NULL /* smap */ }; -static struct dentry *devtree_follow_link(struct inode *inode, +static struct dentry *devtree_follow_link(struct dentry *dentry, struct dentry *base) { struct proc_dir_entry * de; char *link; - de = (struct proc_dir_entry *) inode->u.generic_ip; + de = (struct proc_dir_entry *) dentry->inode->u.generic_ip; link = (char *) de->data; return lookup_dentry(link, base, 1); } -static int devtree_readlink(struct inode *inode, char *buffer, int buflen) +static int devtree_readlink(struct dentry *dentry, char *buffer, int buflen) { struct proc_dir_entry * de; char *link; int linklen; - de = (struct proc_dir_entry *) inode->u.generic_ip; + de = (struct proc_dir_entry *) dentry->inode->u.generic_ip; link = (char *) de->data; linklen = strlen(link); if (linklen > buflen) diff -u --recursive --new-file v2.1.77/linux/fs/proc/root.c linux/fs/proc/root.c --- v2.1.77/linux/fs/proc/root.c Wed Oct 15 16:04:23 1997 +++ linux/fs/proc/root.c Sun Jan 4 00:53:41 1998 @@ -368,7 +368,7 @@ /* * /proc/self: */ -static int proc_self_readlink(struct inode * inode, char * buffer, int buflen) +static int proc_self_readlink(struct dentry *dentry, char *buffer, int buflen) { int len; char tmp[30]; @@ -380,12 +380,12 @@ return len; } -static struct dentry * proc_self_follow_link(struct inode *inode, struct dentry *base) +static struct dentry * proc_self_follow_link(struct dentry *dentry, + struct dentry *base) { - int len; char tmp[30]; - len = sprintf(tmp, "%d", current->pid); + sprintf(tmp, "%d", current->pid); return lookup_dentry(tmp, base, 1); } diff -u --recursive --new-file v2.1.77/linux/fs/romfs/inode.c linux/fs/romfs/inode.c --- v2.1.77/linux/fs/romfs/inode.c Thu Sep 11 09:02:24 1997 +++ linux/fs/romfs/inode.c Sun Jan 4 00:53:43 1998 @@ -391,8 +391,9 @@ */ static int -romfs_readpage(struct inode * inode, struct page * page) +romfs_readpage(struct dentry * dentry, struct page * page) { + struct inode *inode = dentry->d_inode; unsigned long buf; unsigned long offset, avail, readlen; int result = -EIO; @@ -428,8 +429,9 @@ } static int -romfs_readlink(struct inode *inode, char *buffer, int len) +romfs_readlink(struct dentry *dentry, char *buffer, int len) { + struct inode *inode = dentry->d_inode; int mylen; char buf[ROMFS_MAXFN]; /* XXX dynamic */ @@ -450,11 +452,12 @@ return mylen; } -static struct dentry *romfs_follow_link(struct inode *inode, struct dentry *base) +static struct dentry *romfs_follow_link(struct dentry *dentry, + struct dentry *base) { + struct inode *inode = dentry->d_inode; char *link; int len, cnt; - struct dentry *dentry; len = inode->i_size; diff -u --recursive --new-file v2.1.77/linux/fs/smbfs/dir.c linux/fs/smbfs/dir.c --- v2.1.77/linux/fs/smbfs/dir.c Sun Dec 21 16:17:45 1997 +++ linux/fs/smbfs/dir.c Sun Jan 4 00:53:42 1998 @@ -89,7 +89,7 @@ /* * Make sure our inode is up-to-date. */ - result = smb_revalidate_inode(dir); + result = smb_revalidate_inode(dentry); if (result) goto out; /* @@ -183,7 +183,7 @@ } if (server->conn_pid) - error = smb_revalidate_inode(dir); + error = smb_revalidate_inode(dentry); return error; } @@ -235,7 +235,7 @@ #endif valid = 0; } else if (!valid) - valid = (smb_revalidate_inode(inode) == 0); + valid = (smb_revalidate_inode(dentry) == 0); } else { /* diff -u --recursive --new-file v2.1.77/linux/fs/smbfs/file.c linux/fs/smbfs/file.c --- v2.1.77/linux/fs/smbfs/file.c Fri Dec 19 15:53:01 1997 +++ linux/fs/smbfs/file.c Sun Jan 4 00:53:42 1998 @@ -52,24 +52,17 @@ * Read a page synchronously. */ static int -smb_readpage_sync(struct inode *inode, struct page *page) +smb_readpage_sync(struct dentry *dentry, struct page *page) { + struct inode *inode = dentry->d_inode; char *buffer = (char *) page_address(page); unsigned long offset = page->offset; - struct dentry * dentry = inode->u.smbfs_i.dentry; int rsize = smb_get_rsize(SMB_SERVER(inode)); int count = PAGE_SIZE; int result; clear_bit(PG_error, &page->flags); - result = -EIO; - if (!dentry) { - printk("smb_readpage_sync: no dentry for inode %ld\n", - inode->i_ino); - goto io_error; - } - #ifdef SMBFS_DEBUG_VERBOSE printk("smb_readpage_sync: file %s/%s, count=%d@%ld, rsize=%d\n", dentry->d_parent->d_name.name, dentry->d_name.name, count, offset, rsize); @@ -110,7 +103,7 @@ } int -smb_readpage(struct inode *inode, struct page *page) +smb_readpage(struct dentry *dentry, struct page *page) { int error; @@ -121,7 +114,7 @@ #endif set_bit(PG_locked, &page->flags); atomic_inc(&page->count); - error = smb_readpage_sync(inode, page); + error = smb_readpage_sync(dentry, page); free_page(page_address(page)); return error; } @@ -131,9 +124,10 @@ * Offset is the data offset within the page. */ static int -smb_writepage_sync(struct inode *inode, struct page *page, +smb_writepage_sync(struct dentry *dentry, struct page *page, unsigned long offset, unsigned int count) { + struct inode *inode = dentry->d_inode; u8 *buffer = (u8 *) page_address(page) + offset; int wsize = smb_get_wsize(SMB_SERVER(inode)); int result, written = 0; @@ -141,8 +135,7 @@ offset += page->offset; #ifdef SMBFS_DEBUG_VERBOSE printk("smb_writepage_sync: file %s/%s, count=%d@%ld, wsize=%d\n", -((struct dentry *) inode->u.smbfs_i.dentry)->d_parent->d_name.name, -((struct dentry *) inode->u.smbfs_i.dentry)->d_name.name, count, offset, wsize); +dentry->d_parent->d_name.name, dentry->d_name.name, count, offset, wsize); #endif do { @@ -185,7 +178,7 @@ * (for now), and we currently do this synchronously only. */ static int -smb_writepage(struct inode *inode, struct page *page) +smb_writepage(struct dentry *dentry, struct page *page) { int result; @@ -195,21 +188,21 @@ #endif set_bit(PG_locked, &page->flags); atomic_inc(&page->count); - result = smb_writepage_sync(inode, page, 0, PAGE_SIZE); + result = smb_writepage_sync(dentry, page, 0, PAGE_SIZE); free_page(page_address(page)); return result; } static int -smb_updatepage(struct inode *inode, struct page *page, const char *buffer, +smb_updatepage(struct dentry *dentry, struct page *page, const char *buffer, unsigned long offset, unsigned int count, int sync) { unsigned long page_addr = page_address(page); int result; - pr_debug("SMB: smb_updatepage(%x/%ld %d@%ld, sync=%d)\n", - inode->i_dev, inode->i_ino, - count, page->offset+offset, sync); + pr_debug("SMBFS: smb_updatepage(%s/%s %d@%ld, sync=%d)\n", + dentry->d_parent->d_name.name, dentry->d_name.name, + count, page->offset+offset, sync); #ifdef SMBFS_PARANOIA if (test_bit(PG_locked, &page->flags)) @@ -220,7 +213,7 @@ if (copy_from_user((char *) page_addr + offset, buffer, count)) goto bad_fault; - result = smb_writepage_sync(inode, page, offset, count); + result = smb_writepage_sync(dentry, page, offset, count); out: free_page(page_addr); return result; @@ -240,7 +233,6 @@ smb_file_read(struct file * file, char * buf, size_t count, loff_t *ppos) { struct dentry * dentry = file->f_dentry; - struct inode * inode = dentry->d_inode; ssize_t status; #ifdef SMBFS_DEBUG_VERBOSE @@ -249,7 +241,7 @@ (unsigned long) count, (unsigned long) *ppos); #endif - status = smb_revalidate_inode(inode); + status = smb_revalidate_inode(dentry); if (status) { #ifdef SMBFS_PARANOIA @@ -261,7 +253,8 @@ #ifdef SMBFS_DEBUG_VERBOSE printk("smb_file_read: before read, size=%ld, pages=%ld, flags=%x, atime=%ld\n", -inode->i_size, inode->i_nrpages, inode->i_flags, inode->i_atime); +dentry->d_inode->i_size, dentry->d_inode->i_nrpages, dentry->d_inode->i_flags, +dentry->d_inode->i_atime); #endif status = generic_file_read(file, buf, count, ppos); out: @@ -272,16 +265,14 @@ smb_file_mmap(struct file * file, struct vm_area_struct * vma) { struct dentry * dentry = file->f_dentry; - struct inode * inode = dentry->d_inode; int status; #ifdef SMBFS_DEBUG_VERBOSE printk("smb_file_mmap: file %s/%s, address %lu - %lu\n", -dentry->d_parent->d_name.name, dentry->d_name.name, -vma->vm_start, vma->vm_end); +dentry->d_parent->d_name.name, dentry->d_name.name, vma->vm_start, vma->vm_end); #endif - status = smb_revalidate_inode(inode); + status = smb_revalidate_inode(dentry); if (status) { #ifdef SMBFS_PARANOIA @@ -302,16 +293,15 @@ smb_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { struct dentry * dentry = file->f_dentry; - struct inode * inode = dentry->d_inode; ssize_t result; #ifdef SMBFS_DEBUG_VERBOSE printk("smb_file_write: file %s/%s, count=%lu@%lu, pages=%ld\n", dentry->d_parent->d_name.name, dentry->d_name.name, -(unsigned long) count, (unsigned long) *ppos, inode->i_nrpages); +(unsigned long) count, (unsigned long) *ppos, dentry->d_inode->i_nrpages); #endif - result = smb_revalidate_inode(inode); + result = smb_revalidate_inode(dentry); if (result) { #ifdef SMBFS_PARANOIA @@ -330,7 +320,8 @@ result = generic_file_write(file, buf, count, ppos); #ifdef SMBFS_DEBUG_VERBOSE printk("smb_file_write: pos=%ld, size=%ld, mtime=%ld, atime=%ld\n", -(long) file->f_pos, inode->i_size, inode->i_mtime, inode->i_atime); +(long) file->f_pos, dentry->d_inode->i_size, dentry->d_inode->i_mtime, +dentry->d_inode->i_atime); #endif } out: diff -u --recursive --new-file v2.1.77/linux/fs/smbfs/inode.c linux/fs/smbfs/inode.c --- v2.1.77/linux/fs/smbfs/inode.c Sun Dec 21 16:17:45 1997 +++ linux/fs/smbfs/inode.c Sun Jan 4 00:53:42 1998 @@ -186,8 +186,9 @@ * invalidate our local caches. */ int -smb_revalidate_inode(struct inode *inode) +smb_revalidate_inode(struct dentry *dentry) { + struct inode *inode = dentry->d_inode; time_t last_time; int error = 0; @@ -224,8 +225,7 @@ { #ifdef SMBFS_DEBUG_VERBOSE printk("smb_revalidate: %s/%s changed, old=%ld, new=%ld\n", -((struct dentry *)inode->u.smbfs_i.dentry)->d_parent->d_name.name, -((struct dentry *)inode->u.smbfs_i.dentry)->d_name.name, +dentry->d_parent->d_name.name, dentry->d_name.name, (long) last_time, (long) inode->i_mtime); #endif if (!S_ISDIR(inode->i_mode)) @@ -492,22 +492,15 @@ } int -smb_notify_change(struct inode *inode, struct iattr *attr) +smb_notify_change(struct dentry *dentry, struct iattr *attr) { - struct smb_sb_info *server = SMB_SERVER(inode); - struct dentry *dentry = inode->u.smbfs_i.dentry; + struct inode *inode = dentry->d_inode; + struct smb_sb_info *server = server_from_dentry(dentry); unsigned int mask = (S_IFREG | S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO); int error, changed, refresh = 0; struct smb_fattr fattr; - error = -EIO; - if (!dentry) - { - printk("smb_notify_change: no dentry for inode!\n"); - goto out; - } - - error = smb_revalidate_inode(inode); + error = smb_revalidate_inode(dentry); if (error) goto out; diff -u --recursive --new-file v2.1.77/linux/fs/stat.c linux/fs/stat.c --- v2.1.77/linux/fs/stat.c Thu Jul 17 10:06:07 1997 +++ linux/fs/stat.c Sun Jan 4 00:53:41 1998 @@ -20,10 +20,11 @@ * Revalidate the inode. This is required for proper NFS attribute caching. */ static __inline__ int -do_revalidate(struct inode *inode) +do_revalidate(struct dentry *dentry) { + struct inode * inode = dentry->d_inode; if (inode->i_op && inode->i_op->revalidate) - return inode->i_op->revalidate(inode); + return inode->i_op->revalidate(dentry); return 0; } @@ -128,10 +129,9 @@ error = PTR_ERR(dentry); if (!IS_ERR(dentry)) { - struct inode * inode = dentry->d_inode; - error = do_revalidate(inode); + error = do_revalidate(dentry); if (!error) - error = cp_old_stat(inode, statbuf); + error = cp_old_stat(dentry->d_inode, statbuf); dput(dentry); } @@ -150,10 +150,9 @@ error = PTR_ERR(dentry); if (!IS_ERR(dentry)) { - struct inode * inode = dentry->d_inode; - error = do_revalidate(inode); + error = do_revalidate(dentry); if (!error) - error = cp_new_stat(inode,statbuf); + error = cp_new_stat(dentry->d_inode, statbuf); dput(dentry); } @@ -177,10 +176,9 @@ error = PTR_ERR(dentry); if (!IS_ERR(dentry)) { - struct inode * inode = dentry->d_inode; - error = do_revalidate(inode); + error = do_revalidate(dentry); if (!error) - error = cp_old_stat(inode, statbuf); + error = cp_old_stat(dentry->d_inode, statbuf); dput(dentry); } @@ -200,10 +198,9 @@ error = PTR_ERR(dentry); if (!IS_ERR(dentry)) { - struct inode * inode = dentry->d_inode; - error = do_revalidate(inode); + error = do_revalidate(dentry); if (!error) - error = cp_new_stat(inode,statbuf); + error = cp_new_stat(dentry->d_inode, statbuf); dput(dentry); } @@ -225,11 +222,10 @@ lock_kernel(); if (fd < NR_OPEN && (f = current->files->fd[fd]) != NULL) { struct dentry * dentry = f->f_dentry; - struct inode * inode = dentry->d_inode; - err = do_revalidate(inode); + err = do_revalidate(dentry); if (!err) - err = cp_old_stat(inode,statbuf); + err = cp_old_stat(dentry->d_inode, statbuf); } unlock_kernel(); return err; @@ -245,11 +241,10 @@ lock_kernel(); if (fd < NR_OPEN && (f = current->files->fd[fd]) != NULL) { struct dentry * dentry = f->f_dentry; - struct inode * inode = dentry->d_inode; - err = do_revalidate(inode); + err = do_revalidate(dentry); if (!err) - err = cp_new_stat(inode,statbuf); + err = cp_new_stat(dentry->d_inode, statbuf); } unlock_kernel(); return err; @@ -271,9 +266,10 @@ struct inode * inode = dentry->d_inode; error = -EINVAL; - if (inode->i_op && inode->i_op->readlink && !(error = do_revalidate(inode))) { + if (inode->i_op && inode->i_op->readlink && + !(error = do_revalidate(dentry))) { UPDATE_ATIME(inode); - error = inode->i_op->readlink(inode,buf,bufsiz); + error = inode->i_op->readlink(dentry, buf, bufsiz); } dput(dentry); } diff -u --recursive --new-file v2.1.77/linux/fs/sysv/inode.c linux/fs/sysv/inode.c --- v2.1.77/linux/fs/sysv/inode.c Sat Oct 25 02:44:18 1997 +++ linux/fs/sysv/inode.c Sun Jan 4 00:53:41 1998 @@ -873,8 +873,9 @@ } /* To avoid inconsistencies between inodes in memory and inodes on disk. */ -extern int sysv_notify_change(struct inode *inode, struct iattr *attr) +extern int sysv_notify_change(struct dentry *dentry, struct iattr *attr) { + struct inode *inode = dentry->d_inode; int error; if ((error = inode_change_ok(inode, attr)) != 0) diff -u --recursive --new-file v2.1.77/linux/fs/sysv/symlink.c linux/fs/sysv/symlink.c --- v2.1.77/linux/fs/sysv/symlink.c Thu Jul 17 10:06:08 1997 +++ linux/fs/sysv/symlink.c Sun Jan 4 00:53:41 1998 @@ -20,8 +20,8 @@ #include -static int sysv_readlink(struct inode *, char *, int); -static struct dentry *sysv_follow_link(struct inode *, struct dentry *); +static int sysv_readlink(struct dentry *, char *, int); +static struct dentry *sysv_follow_link(struct dentry *, struct dentry *); /* * symlinks can't do much... @@ -46,8 +46,10 @@ NULL /* permission */ }; -static struct dentry *sysv_follow_link(struct inode * inode, struct dentry * base) +static struct dentry *sysv_follow_link(struct dentry * dentry, + struct dentry * base) { + struct inode *inode = dentry->d_inode; struct buffer_head * bh; bh = sysv_file_bread(inode, 0, 0); @@ -61,8 +63,9 @@ return base; } -static int sysv_readlink(struct inode * inode, char * buffer, int buflen) +static int sysv_readlink(struct dentry * dentry, char * buffer, int buflen) { + struct inode *inode = dentry->d_inode; struct buffer_head * bh; char * bh_data; int i; diff -u --recursive --new-file v2.1.77/linux/fs/ufs/ufs_symlink.c linux/fs/ufs/ufs_symlink.c --- v2.1.77/linux/fs/ufs/ufs_symlink.c Wed Dec 10 11:12:45 1997 +++ linux/fs/ufs/ufs_symlink.c Sun Jan 4 00:53:41 1998 @@ -19,8 +19,9 @@ extern int ufs_bmap (struct inode *, int); static int -ufs_readlink(struct inode * inode, char * buffer, int buflen) +ufs_readlink(struct dentry * dentry, char * buffer, int buflen) { + struct inode * inode = dentry->d_inode; unsigned long int block; struct buffer_head * bh = NULL; char * link; @@ -71,8 +72,9 @@ * XXX - blatantly stolen from minix fs */ static struct dentry * -ufs_follow_link(struct inode * inode, struct dentry * base) +ufs_follow_link(struct dentry * dentry, struct dentry * base) { + struct inode * inode = dentry->d_inode; unsigned long int block; struct buffer_head * bh = NULL; char * link; diff -u --recursive --new-file v2.1.77/linux/include/linux/dcache.h linux/include/linux/dcache.h --- v2.1.77/linux/include/linux/dcache.h Tue Dec 2 09:49:40 1997 +++ linux/include/linux/dcache.h Sun Jan 4 00:53:40 1998 @@ -66,6 +66,7 @@ struct dentry_operations *d_op; struct super_block * d_sb; /* The root of the dentry tree */ unsigned long d_reftime; /* last time referenced */ + void * d_fsdata; /* fs-specific data */ }; struct dentry_operations { @@ -73,6 +74,7 @@ int (*d_hash) (struct dentry *,struct qstr *); int (*d_compare) (struct dentry *,struct qstr *, struct qstr *); void (*d_delete)(struct dentry *); + void (*d_release)(struct dentry *); }; /* the dentry parameter passed to d_hash and d_compare is the parent diff -u --recursive --new-file v2.1.77/linux/include/linux/ext2_fs.h linux/include/linux/ext2_fs.h --- v2.1.77/linux/include/linux/ext2_fs.h Tue Sep 23 16:48:49 1997 +++ linux/include/linux/ext2_fs.h Sun Jan 4 00:53:40 1998 @@ -499,9 +499,10 @@ extern int ext2_rmdir (struct inode *,struct dentry *); extern int ext2_unlink (struct inode *,struct dentry *); extern int ext2_symlink (struct inode *,struct dentry *,const char *); -extern int ext2_link (struct inode *, struct inode *, struct dentry *); +extern int ext2_link (struct dentry *, struct inode *, struct dentry *); extern int ext2_mknod (struct inode *, struct dentry *, int, int); -extern int ext2_rename (struct inode *, struct dentry *,struct inode *, struct dentry *); +extern int ext2_rename (struct inode *, struct dentry *, + struct inode *, struct dentry *); /* super.c */ extern void ext2_error (struct super_block *, const char *, const char *, ...) diff -u --recursive --new-file v2.1.77/linux/include/linux/fs.h linux/include/linux/fs.h --- v2.1.77/linux/include/linux/fs.h Tue Dec 23 16:31:00 1997 +++ linux/include/linux/fs.h Sun Jan 4 01:28:45 1998 @@ -571,24 +571,25 @@ struct file_operations * default_file_ops; int (*create) (struct inode *,struct dentry *,int); int (*lookup) (struct inode *,struct dentry *); - int (*link) (struct inode *,struct inode *,struct dentry *); + int (*link) (struct dentry *,struct inode *,struct dentry *); int (*unlink) (struct inode *,struct dentry *); int (*symlink) (struct inode *,struct dentry *,const char *); int (*mkdir) (struct inode *,struct dentry *,int); int (*rmdir) (struct inode *,struct dentry *); int (*mknod) (struct inode *,struct dentry *,int,int); - int (*rename) (struct inode *,struct dentry *,struct inode *,struct dentry *); - int (*readlink) (struct inode *,char *,int); - struct dentry * (*follow_link) (struct inode *, struct dentry *); - int (*readpage) (struct inode *, struct page *); - int (*writepage) (struct inode *, struct page *); + int (*rename) (struct inode *, struct dentry *, + struct inode *, struct dentry *); + int (*readlink) (struct dentry *, char *,int); + struct dentry * (*follow_link) (struct dentry *, struct dentry *); + int (*readpage) (struct dentry *, struct page *); + int (*writepage) (struct dentry *, struct page *); int (*bmap) (struct inode *,int); void (*truncate) (struct inode *); int (*permission) (struct inode *, int); int (*smap) (struct inode *,int); - int (*updatepage) (struct inode *, struct page *, const char *, + int (*updatepage) (struct dentry *, struct page *, const char *, unsigned long, unsigned int, int); - int (*revalidate) (struct inode *); + int (*revalidate) (struct dentry *); }; struct super_operations { @@ -596,7 +597,7 @@ void (*write_inode) (struct inode *); void (*put_inode) (struct inode *); void (*delete_inode) (struct inode *); - int (*notify_change) (struct inode *, struct iattr *); + int (*notify_change) (struct dentry *, struct iattr *); void (*put_super) (struct super_block *); void (*write_super) (struct super_block *); int (*statfs) (struct super_block *, struct statfs *, int); @@ -630,7 +631,7 @@ extern char * getname(const char * filename); extern void putname(char * name); -extern int do_truncate(struct inode *, unsigned long); +extern int do_truncate(struct dentry *, unsigned long); extern int register_blkdev(unsigned int, const char *, struct file_operations *); extern int unregister_blkdev(unsigned int major, const char * name); extern int blkdev_open(struct inode * inode, struct file * filp); @@ -710,7 +711,7 @@ extern int fsync_dev(kdev_t dev); 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 notify_change(struct dentry *, struct iattr *); extern int permission(struct inode * inode,int mask); extern int get_write_access(struct inode *inode); extern void put_write_access(struct inode *inode); @@ -800,7 +801,7 @@ extern int brw_page(int, struct page *, kdev_t, int [], int, int); -extern int generic_readpage(struct inode *, struct page *); +extern int generic_readpage(struct dentry *, struct page *); extern int generic_file_mmap(struct file *, struct vm_area_struct *); extern ssize_t generic_file_read(struct file *, char *, size_t, loff_t *); extern ssize_t generic_file_write(struct file *, const char*, size_t, loff_t*); @@ -831,7 +832,6 @@ extern int inode_change_ok(struct inode *, struct iattr *); extern void inode_setattr(struct inode *, struct iattr *); -extern int notify_change(struct inode * inode, struct iattr * attr); /* kludge to get SCSI modules working */ #include diff -u --recursive --new-file v2.1.77/linux/include/linux/msdos_fs.h linux/include/linux/msdos_fs.h --- v2.1.77/linux/include/linux/msdos_fs.h Sat Oct 25 02:44:18 1997 +++ linux/include/linux/msdos_fs.h Sun Jan 4 01:34:51 1998 @@ -225,7 +225,7 @@ /* inode.c */ extern int fat_bmap(struct inode *inode,int block); -extern int fat_notify_change(struct inode *,struct iattr *); +extern int fat_notify_change(struct dentry *, struct iattr *); extern void fat_put_inode(struct inode *inode); extern void fat_delete_inode(struct inode *inode); extern void fat_put_super(struct super_block *sb); diff -u --recursive --new-file v2.1.77/linux/include/linux/nfs_fs.h linux/include/linux/nfs_fs.h --- v2.1.77/linux/include/linux/nfs_fs.h Sun Dec 21 22:36:17 1997 +++ linux/include/linux/nfs_fs.h Sun Jan 4 01:28:46 1998 @@ -11,9 +11,10 @@ #include #include -#include #include + #include +#include #include /* @@ -53,11 +54,12 @@ */ #define NFS_SUPER_MAGIC 0x6969 +#define NFS_FH(dentry) ((struct nfs_fh *) ((dentry)->d_fsdata)) +#define NFS_DSERVER(dentry) (&(dentry)->d_sb->u.nfs_sb.s_server) #define NFS_SERVER(inode) (&(inode)->i_sb->u.nfs_sb.s_server) #define NFS_CLIENT(inode) (NFS_SERVER(inode)->client) #define NFS_ADDR(inode) (RPC_PEERADDR(NFS_CLIENT(inode))) #define NFS_CONGESTED(inode) (RPC_CONGESTED(NFS_CLIENT(inode))) -#define NFS_FH(inode) (&(inode)->u.nfs_i.fhandle) #define NFS_READTIME(inode) ((inode)->u.nfs_i.read_cache_jiffies) #define NFS_OLDMTIME(inode) ((inode)->u.nfs_i.read_cache_mtime) @@ -138,8 +140,8 @@ extern struct inode *nfs_fhget(struct super_block *, struct nfs_fh *, struct nfs_fattr *); extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *); -extern int nfs_revalidate(struct inode *); -extern int _nfs_revalidate_inode(struct nfs_server *, struct inode *); +extern int nfs_revalidate(struct dentry *); +extern int _nfs_revalidate_inode(struct nfs_server *, struct dentry *); /* * linux/fs/nfs/file.c @@ -150,6 +152,7 @@ * linux/fs/nfs/dir.c */ extern struct inode_operations nfs_dir_inode_operations; +extern struct dentry_operations nfs_dentry_operations; extern void nfs_free_dircache(void); extern void nfs_invalidate_dircache(struct inode *); extern void nfs_invalidate_dircache_sb(struct super_block *); @@ -162,25 +165,24 @@ /* * linux/fs/nfs/locks.c */ -extern int nfs_lock(struct file *file, int cmd, struct file_lock *fl); +extern int nfs_lock(struct file *, int, struct file_lock *); /* * linux/fs/nfs/write.c */ -extern int nfs_writepage(struct inode *, struct page *); +extern int nfs_writepage(struct dentry *, struct page *); extern int nfs_check_failed_request(struct inode *); extern int nfs_check_error(struct inode *); extern int nfs_flush_dirty_pages(struct inode *, pid_t, off_t, off_t); extern int nfs_truncate_dirty_pages(struct inode *, unsigned long); extern void nfs_invalidate_pages(struct inode *); -extern int nfs_updatepage(struct inode *, struct page *, const char *, +extern int nfs_updatepage(struct dentry *, struct page *, const char *, unsigned long, unsigned int, int); /* * linux/fs/nfs/read.c */ -extern int nfs_readpage(struct inode *, struct page *); -extern int nfs_readpage_sync(struct inode *, struct page *); +extern int nfs_readpage(struct dentry *, struct page *); /* * linux/fs/mount_clnt.c @@ -192,11 +194,12 @@ * inline functions */ static inline int -nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) +nfs_revalidate_inode(struct nfs_server *server, struct dentry *dentry) { + struct inode *inode = dentry->d_inode; if (jiffies - NFS_READTIME(inode) < NFS_ATTRTIMEO(inode)) return 0; - return _nfs_revalidate_inode(server, inode); + return _nfs_revalidate_inode(server, dentry); } extern struct nfs_wreq * nfs_failed_requests; diff -u --recursive --new-file v2.1.77/linux/include/linux/nfs_fs_i.h linux/include/linux/nfs_fs_i.h --- v2.1.77/linux/include/linux/nfs_fs_i.h Wed Sep 3 20:52:44 1997 +++ linux/include/linux/nfs_fs_i.h Sun Jan 4 00:53:40 1998 @@ -16,11 +16,6 @@ struct pipe_inode_info pipeinfo; /* - * The file handle - */ - struct nfs_fh fhandle; - - /* * Various flags */ unsigned short flags; diff -u --recursive --new-file v2.1.77/linux/include/linux/smb_fs.h linux/include/linux/smb_fs.h --- v2.1.77/linux/include/linux/smb_fs.h Fri Dec 19 15:53:05 1997 +++ linux/include/linux/smb_fs.h Sun Jan 4 01:34:51 1998 @@ -94,9 +94,9 @@ struct super_block *smb_read_super(struct super_block *, void *, int); void smb_get_inode_attr(struct inode *, struct smb_fattr *); void smb_invalidate_inodes(struct smb_sb_info *); -int smb_revalidate_inode(struct inode *); +int smb_revalidate_inode(struct dentry *); int smb_refresh_inode(struct inode *); -int smb_notify_change(struct inode *, struct iattr *); +int smb_notify_change(struct dentry *, struct iattr *); unsigned long smb_invent_inos(unsigned long); struct inode *smb_iget(struct super_block *, struct smb_fattr *); diff -u --recursive --new-file v2.1.77/linux/mm/filemap.c linux/mm/filemap.c --- v2.1.77/linux/mm/filemap.c Tue Dec 23 16:31:00 1997 +++ linux/mm/filemap.c Sun Jan 4 00:53:41 1998 @@ -260,8 +260,10 @@ * that we could use for the cache (if it is 0 we can try to create one, * this is all overlapped with the IO on the previous page finishing anyway) */ -static unsigned long try_to_read_ahead(struct inode * inode, unsigned long offset, unsigned long page_cache) +static unsigned long try_to_read_ahead(struct dentry * dentry, + unsigned long offset, unsigned long page_cache) { + struct inode *inode = dentry->d_inode; struct page * page; struct page ** hash; @@ -282,7 +284,7 @@ */ page = mem_map + MAP_NR(page_cache); add_to_page_cache(page, inode, offset, hash); - inode->i_op->readpage(inode, page); + inode->i_op->readpage(dentry, page); page_cache = 0; } release_page(page); @@ -445,9 +447,9 @@ return max_readahead[MAJOR(inode->i_dev)][MINOR(inode->i_dev)]; } -static inline unsigned long generic_file_readahead(int reada_ok, struct file * filp, struct inode * inode, - unsigned long ppos, struct page * page, - unsigned long page_cache) +static inline unsigned long generic_file_readahead(int reada_ok, + struct file * filp, struct inode * inode, + unsigned long ppos, struct page * page, unsigned long page_cache) { unsigned long max_ahead, ahead; unsigned long raend; @@ -511,7 +513,8 @@ ahead = 0; while (ahead < max_ahead) { ahead += PAGE_SIZE; - page_cache = try_to_read_ahead(inode, raend + ahead, page_cache); + page_cache = try_to_read_ahead(filp->f_dentry, raend + ahead, + page_cache); } /* * If we tried to read ahead some pages, @@ -559,7 +562,8 @@ ssize_t generic_file_read(struct file * filp, char * buf, size_t count, loff_t *ppos) { - struct inode *inode = filp->f_dentry->d_inode; + struct dentry *dentry = filp->f_dentry; + struct inode *inode = dentry->d_inode; ssize_t error, read; size_t pos, pgpos, page_cache; int reada_ok; @@ -716,7 +720,7 @@ if (reada_ok && filp->f_ramax > MIN_READAHEAD) filp->f_ramax = MIN_READAHEAD; - error = inode->i_op->readpage(inode, page); + error = inode->i_op->readpage(dentry, page); if (!error) goto found_page; release_page(page); @@ -728,7 +732,7 @@ * Try to re-read it _once_. We do this synchronously, * because this happens only if there were errors. */ - error = inode->i_op->readpage(inode, page); + error = inode->i_op->readpage(dentry, page); if (!error) { wait_on_page(page); if (PageUptodate(page) && !PageError(page)) @@ -763,9 +767,10 @@ */ static unsigned long filemap_nopage(struct vm_area_struct * area, unsigned long address, int no_share) { + struct dentry * dentry = area->vm_dentry; + struct inode * inode = dentry->d_inode; unsigned long offset; struct page * page, **hash; - struct inode * inode = area->vm_dentry->d_inode; unsigned long old_page, new_page; new_page = 0; @@ -846,14 +851,14 @@ new_page = 0; add_to_page_cache(page, inode, offset, hash); - if (inode->i_op->readpage(inode, page) != 0) + if (inode->i_op->readpage(dentry, page) != 0) goto failure; /* * Do a very limited read-ahead if appropriate */ if (PageLocked(page)) - new_page = try_to_read_ahead(inode, offset + PAGE_SIZE, 0); + new_page = try_to_read_ahead(dentry, offset + PAGE_SIZE, 0); goto found_page; page_locked_wait: @@ -868,7 +873,7 @@ * because there really aren't any performance issues here * and we need to check for errors. */ - if (inode->i_op->readpage(inode, page) != 0) + if (inode->i_op->readpage(dentry, page) != 0) goto failure; wait_on_page(page); if (PageError(page)) @@ -1305,7 +1310,8 @@ generic_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { - struct inode *inode = file->f_dentry->d_inode; + struct dentry *dentry = file->f_dentry; + struct inode *inode = dentry->d_inode; struct page *page, **hash; unsigned long page_cache = 0; unsigned long pgpos, offset; @@ -1367,10 +1373,10 @@ */ if (!PageUptodate(page)) { if (bytes < PAGE_SIZE && pgpos < inode->i_size) { + status = -EIO; /* two tries ... error out */ if (didread < 2) - status = inode->i_op->readpage(inode, page); - else - status = -EIO; /* two tries ... error out */ + status = inode->i_op->readpage(dentry, + page); if (status < 0) goto done_with_page; didread++; @@ -1380,7 +1386,7 @@ } /* Alright, the page is there. Now update it. */ - status = inode->i_op->updatepage(inode, page, buf, + status = inode->i_op->updatepage(dentry, page, buf, offset, bytes, sync); done_with_page: __free_page(page);