]> git.neil.brown.name Git - history.git/commitdiff
Import 2.1.78pre1 2.1.78pre1
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:14:20 +0000 (15:14 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:14:20 +0000 (15:14 -0500)
50 files changed:
Documentation/networking/depca.txt [new file with mode: 0644]
Makefile
fs/affs/inode.c
fs/affs/symlink.c
fs/attr.c
fs/autofs/symlink.c
fs/bad_inode.c
fs/buffer.c
fs/coda/file.c
fs/coda/super.c
fs/coda/symlink.c
fs/dcache.c
fs/ext2/inode.c
fs/ext2/namei.c
fs/ext2/symlink.c
fs/fat/inode.c
fs/isofs/symlink.c
fs/lockd/clntproc.c
fs/minix/symlink.c
fs/namei.c
fs/ncpfs/dir.c
fs/ncpfs/file.c
fs/ncpfs/inode.c
fs/nfs/dir.c
fs/nfs/file.c
fs/nfs/inode.c
fs/nfs/read.c
fs/nfs/symlink.c
fs/nfs/write.c
fs/nfsd/vfs.c
fs/open.c
fs/proc/link.c
fs/proc/proc_devtree.c
fs/proc/root.c
fs/romfs/inode.c
fs/smbfs/dir.c
fs/smbfs/file.c
fs/smbfs/inode.c
fs/stat.c
fs/sysv/inode.c
fs/sysv/symlink.c
fs/ufs/ufs_symlink.c
include/linux/dcache.h
include/linux/ext2_fs.h
include/linux/fs.h
include/linux/msdos_fs.h
include/linux/nfs_fs.h
include/linux/nfs_fs_i.h
include/linux/smb_fs.h
mm/filemap.c

diff --git a/Documentation/networking/depca.txt b/Documentation/networking/depca.txt
new file mode 100644 (file)
index 0000000..24c6b26
--- /dev/null
@@ -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
+
index 52af638e4e6547b05922655289ce06d8e8a0a482..4dd081e5ee84b0784b8e60bd2f5aa2c5933d2e4d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -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/)
 
index 676e43470569844f7f1153adf05f13287a578ff1..d94d146431912812808582131a4bd5bb07a62536 100644 (file)
@@ -220,8 +220,9 @@ affs_write_inode(struct inode *inode)
 }
 
 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);
index 22042158a17cf78a947dc4ae0b05c60620f74d49..50e0acd3ac50f4cf0ccfc16613f57138e3ad9e7a 100644 (file)
@@ -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 @@ struct inode_operations affs_symlink_inode_operations = {
 };
 
 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 @@ affs_readlink(struct inode *inode, char *buffer, int buflen)
 }
 
 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;
index 5bb5dcc1ea70e242c9f155e97407caf563aea743..e916a2a3d115c30a283b052245dc2532f472886e 100644 (file)
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -81,8 +81,9 @@ void inode_setattr(struct inode * inode, struct iattr * attr)
        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 @@ int notify_change(struct inode * inode, struct iattr * attr)
        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;
 }
index b42955feb05828f3b14742e392a298f7d8284f90..5c5550f91a74244100c27a21bc8a98b00e9ec475 100644 (file)
 #include <linux/sched.h>
 #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);
 }
 
index 4d17002ab53cc91f45f6a43378d077c98fab0ea5..47675bf29da79b51350a893f3d1f278cfa5b58b5 100644 (file)
@@ -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);
index e3a9f837a6bc6bcb1a28bdfd5de3199953b3dcdf..9d077d7075a79deca1051795d44534214b9ad342 100644 (file)
@@ -1522,8 +1522,9 @@ void mark_buffer_uptodate(struct buffer_head * bh, int on)
  * 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;
index b6f068e911d4f165ded1a1a8c94f1998bd3837ca..e7ba48356e9e571d8f2a5b8c48a74f7470e321cb 100644 (file)
 #include <linux/coda_cache.h>
 
 /* 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 @@ struct file_operations coda_file_operations = {
 };
 
 /*  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 @@ static int coda_readpage(struct inode * inode, struct page * page)
 
         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;
index 87e8f1b6971e3d2a4e89fd8d02a3d202ca861f1a..6b00a528931e916cf212e9e4543b3729e8923195 100644 (file)
@@ -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 @@ static struct super_block * coda_read_super(struct super_block *sb,
        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 @@ static struct super_block * coda_read_super(struct super_block *sb,
 
 error:
 EXIT;  
-       MOD_DEC_USE_COUNT;
        if (sbi) {
                sbi->sbi_vcomm = NULL;
                sbi->sbi_root = NULL;
@@ -154,6 +154,7 @@ EXIT;
                 coda_cnode_free(ITOC(root));
         }
         sb->s_dev = 0;
+       MOD_DEC_USE_COUNT;
         return NULL;
 }
 
@@ -224,8 +225,9 @@ static void coda_delete_inode(struct inode *inode)
        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;
index 8b8d71edfab23b18f3a7f2145045bf5510e58d2a..80160d94cccf52e3d00c75de42a8b4cc4547b19c 100644 (file)
@@ -24,8 +24,8 @@
 #include <linux/coda_cnode.h>
 #include <linux/coda_cache.h>
 
-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 @@ struct inode_operations coda_symlink_inode_operations = {
         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 @@ static int coda_readlink(struct inode *inode, char *buffer, int length)
        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);
        
index 7d41b0bd5aef96483b74b94355179fde181f1f8f..84917d3ae6259c67863c69b48935dcc14c70e5e7 100644 (file)
@@ -52,6 +52,8 @@ struct {
 
 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 @@ printk("d_alloc: %d unused, pruning dcache\n", dentry_stat.nr_unused);
        dentry->d_name.len = name->len;
        dentry->d_name.hash = name->hash;
        dentry->d_op = NULL;
+       dentry->d_fsdata = NULL;
        return dentry;
 }
 
index 42df76bdaf5faf3fd8a1100013782f371b5384d9..5282a464783d4d41cfca6e8941380da99fabaae5 100644 (file)
@@ -631,23 +631,25 @@ int ext2_sync_inode (struct inode *inode)
        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 @@ int ext2_notify_change(struct inode *inode, struct iattr *iattr)
                inode->u.ext2_i.i_flags &= ~EXT2_IMMUTABLE_FL;
        }
        mark_inode_dirty(inode);
-
-       return 0;
+out:
+       return retval;
 }
 
index f8b005068a5ce39c45837b10e1a01637ffef6d74..5fff3646ee8edb3bbe024c054d227513991c8974 100644 (file)
@@ -793,8 +793,10 @@ out_no_entry:
        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;
index 781f9165d076d3c84ad881b77d73d1432011a726..2996a5f330d7238f986a2444a757db0d581a765c 100644 (file)
@@ -24,8 +24,8 @@
 #include <linux/mm.h>
 #include <linux/stat.h>
 
-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 @@ struct inode_operations ext2_symlink_inode_operations = {
        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 @@ static struct dentry * ext2_follow_link(struct inode * inode, struct dentry *bas
        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;
index 8edc480ac52b9ffd823da856d679c5f75efd0cca..a5bf5a1ace5314d9ed3b1037254e695d85ae11dd 100644 (file)
@@ -783,9 +783,10 @@ void fat_write_inode(struct inode *inode)
 }
 
 
-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);
index 5321e011a6b3f2429a8607c4c7e449781beedac5..fe4abb98795b1dde4d22c640e5e983d6b8990ed5 100644 (file)
@@ -18,8 +18,8 @@
 
 #include <asm/uaccess.h>
 
-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 @@ struct inode_operations isofs_symlink_inode_operations = {
        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 @@ static int isofs_readlink(struct inode * inode, char * buffer, int buflen)
        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);
index d0c70c2765e21948f9c7e82b7a5fedb6df460347..eec09e3adc38a01da504e5e009435db348483e10 100644 (file)
@@ -42,7 +42,7 @@ nlmclnt_setlockargs(struct nlm_rqst *req, struct file_lock *fl)
        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",
index 9f759ecc9ce05754f5189a36674b797f9d7ae5f6..cdc237235b7634d68bb6074e85ae27e8d5886bdc 100644 (file)
@@ -14,8 +14,8 @@
 
 #include <asm/uaccess.h>
 
-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 @@ struct inode_operations minix_symlink_inode_operations = {
        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 @@ static struct dentry * minix_follow_link(struct inode * inode, struct dentry * b
        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 @@ static int minix_readlink(struct inode * inode, char * buffer, int buflen)
 
        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;
index d55e5df494c820551ea0e0812f5050687e0dcf6b..d466a61acd30967bbe16119af1fe314efbdda160 100644 (file)
@@ -221,33 +221,28 @@ void put_write_access(struct inode * inode)
 }
 
 /*
- * 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 @@ static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name)
 }
 
 /*
- * "." 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 @@ static struct dentry * do_follow_link(struct dentry *base, struct dentry *dentry
 
                        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 @@ struct dentry * open_namei(const char * pathname, int flag, int mode)
                        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 @@ static inline int do_link(const char * oldname, const char * newname)
 
        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);
index 005431485a1bca36fbabbc8b0934cc3b5c3ce382..0c40b93d2cdc4a84b7400629abbfc604d5ad5fbf 100644 (file)
@@ -105,10 +105,10 @@ ncp_dir_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
 /*
  * 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 @@ static struct dentry_operations ncp_dentry_operations =
  */
 #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;
-
-  hash = init_name_hash();
-  for (i=0; i<this->len ; i++)
-    hash = partial_name_hash(tolower(this->name[i]),hash);
-  this->hash = end_name_hash(hash);
-  
-  return 0;
+       unsigned long hash;
+       int i;
+
+       if (!ncp_case_sensitive(dentry->d_inode)) {
+               hash = init_name_hash();
+               for (i=0; i<this->len ; i++)
+                       hash = partial_name_hash(tolower(this->name[i]),hash);
+               this->hash = end_name_hash(hash);
+       }
+       return 0;
 }
 
 static int
@@ -202,45 +206,17 @@ dentry->d_parent->d_name.name, dentry->d_name.name);
  */
 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; i<name->len ; 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;
-}
-
 static inline int
 ncp_single_volume(struct ncp_server *server)
 {
index 2f22f25d10eedc6fc198187c94e0eb62f7ebad94..d26fee881e16f713af94b457bf805cb83af9c02a 100644 (file)
 #include <linux/fcntl.h>
 #include <linux/stat.h>
 #include <linux/mm.h>
-#include <linux/ncp_fs.h>
 #include <linux/locks.h>
-#include "ncplib_kernel.h"
 #include <linux/malloc.h>
 
+#include <linux/ncp_fs.h>
+#include "ncplib_kernel.h"
+
 static inline int min(int a, int b)
 {
        return a < b ? a : b;
@@ -65,7 +66,7 @@ int ncp_make_open(struct inode *inode, int right)
                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 @@ printk(KERN_DEBUG "ncp_make_open: failed, result=%d\n", result);
 #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 @@ ncp_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
                }
        }
 
-       inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+       inode->i_mtime = inode->i_atime = CURRENT_TIME;
        
        file->f_pos = pos;
 
index 61cdd03191e7a53b75218a112e7b3b82fa997664..f70374ebfd5b3c10ddb4d1386242532030d0f610 100644 (file)
@@ -37,7 +37,7 @@ extern int close_fp(struct file *filp);
 static void ncp_read_inode(struct inode *);
 static void ncp_put_inode(struct inode *);
 static void ncp_delete_inode(struct inode *);
-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 @@ static void ncp_init_root(struct ncp_server *server,
        i->entryName[0]  = '\0';
 
        root->finfo.opened= 0;
-       info->ino = 1;
+       info->ino = 2; /* tradition */
        info->nw_info = root->finfo;
 }
 
@@ -354,7 +354,7 @@ static void ncp_put_super(struct super_block *sb)
        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 @@ static int ncp_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
        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 @@ static int ncp_notify_change(struct inode *inode, struct iattr *attr)
        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 @@ static int ncp_notify_change(struct inode *inode, struct iattr *attr)
                   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;
 }
 
index 8913be26f855150c4ece21160b5e0a1a97a6761c..0e3ff70d9674fe7a20a767094122eeb76bd8e14a 100644 (file)
@@ -64,7 +64,7 @@ static int nfs_mkdir(struct inode *, struct dentry *, int);
 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 @@ struct inode_operations nfs_dir_inode_operations = {
 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 struct nfs_dirent    dircache[NFS_MAX_DIRCACHE];
 
 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 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
        __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 @@ again:
                                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 @@ done:
        wake_up(&cache->wait);
        wake_up(&readdir_wait);
 
+out:
        return result;
 }
 
@@ -449,11 +457,21 @@ inode->i_ino, inode->i_count, inode->i_nlink);
 #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 @@ void nfs_renew_times(struct dentry * dentry)
        }
 }
 
+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 @@ static int nfs_lookup(struct inode *dir, struct dentry * dentry)
        }
 
        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 @@ dentry->d_parent->d_name.name, dentry->d_name.name,
 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 @@ static int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
        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 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode)
         * 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 @@ static int nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rde
        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 @@ static int nfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
        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_count, dentry->d_inode->i_nlink);
                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 @@ dentry->d_parent->d_name.name, dentry->d_name.name);
 
        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 @@ inode->i_count, inode->i_nlink);
                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 @@ dentry->d_parent->d_name.name, dentry->d_name.name);
         */
        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 @@ out:
 }
 
 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 @@ nfs_link(struct inode *inode, struct inode *dir, struct dentry *dentry)
        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 @@ new_inode->i_count, new_inode->i_nlink);
 
        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)
index 7b53bc8ef32d74e4b17505cd9462348747a81b15..4a575c48c435a3d88e903e51ce25e4c776d3b05b 100644 (file)
@@ -109,15 +109,14 @@ nfs_file_close(struct inode *inode, struct file *file)
 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 @@ nfs_file_read(struct file * file, char * buf, size_t count, loff_t *ppos)
 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 @@ nfs_fsync(struct file *file, struct dentry *dentry)
 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 @@ nfs_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
                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;
 }
 
 /*
index 684a49358d104c4794128d101689b53c90e6a481..26263dc435b40872a36e92fae44fa87d57374173 100644 (file)
@@ -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 @@ struct super_block *
 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 @@ nfs_read_super(struct super_block *sb, void *raw_data, int silent)
        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 @@ nfs_read_super(struct super_block *sb, void *raw_data, int silent)
        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 @@ nfs_read_super(struct super_block *sb, void *raw_data, int silent)
         * 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 @@ nfs_read_super(struct super_block *sb, void *raw_data, int silent)
 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 @@ struct inode *
 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;
+               error = nfs_proc_getattr(&sb->u.nfs_sb.s_server, fhandle,fattr);
+               if (error)
+                       goto out_bad_attr;
        }
-       if (!(inode = iget(sb, fattr->fileid))) {
-               printk("nfs_fhget: iget failed\n");
-               return NULL;
-       }
+       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 @@ printk("nfs_fhget: impossible\n");
                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 @@ printk("nfs_notify_change: revalidate failed, error=%d\n", error);
                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 @@ out:
  * 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 @@ nfs_revalidate(struct inode *inode)
  * 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 @@ nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
                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;
        }
 
index 4ce61f73111be4b7911fddc1c1017c8d31f26c4d..96a5c66bb14cf03777c12cf41cf60bbd0cc406d4 100644 (file)
@@ -65,8 +65,8 @@ nfs_readreq_setup(struct nfs_rreq *req, struct nfs_fh *fh,
 /*
  * 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 @@ nfs_readpage_sync(struct inode *inode, struct page *page)
                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 @@ nfs_readpage_result(struct rpc_task *task)
 }
 
 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 @@ nfs_readpage_async(struct inode *inode, struct page *page)
        }
 
        /* 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 @@ nfs_readpage_async(struct inode *inode, struct page *page)
  *  -  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 @@ nfs_readpage(struct inode *inode, struct page *page)
        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);
index c739ebe6d0f9c7ce7e815ba707001649ce0e9fd6..3ae490c37140e477e2fd15cb336bea2622552d24 100644 (file)
@@ -18,8 +18,8 @@
 
 #include <asm/uaccess.h>
 
-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 @@ struct inode_operations nfs_symlink_inode_operations = {
        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 @@ static int nfs_readlink(struct inode *inode, char *buffer, int buflen)
        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;
 }
index c0db335105b4cbc86fb5b95cbc738ad6b96fed42..6a5f5745893d2840e6ddebe9d8213985336782d0 100644 (file)
@@ -79,6 +79,7 @@ static void                   nfs_wback_result(struct rpc_task *task);
 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 @@ transfer_page_lock(struct nfs_wreq *req)
  * 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 @@ nfs_writepage_sync(struct inode *inode, struct page *page,
                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 @@ update_write_request(struct nfs_wreq *req, unsigned int first,
  * 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 @@ create_write_request(struct inode *inode, struct page *page,
                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 @@ wait_on_write_request(struct nfs_wreq *req)
  * (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 @@ nfs_writepage(struct inode *inode, struct page *page)
  * 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 @@ nfs_updatepage(struct inode *inode, struct page *page, const char *buffer,
         */
        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 @@ nfs_updatepage(struct inode *inode, struct page *page, const char *buffer,
 
        /* 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 @@ nfs_wback_lock(struct rpc_task *task)
 {
        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 @@ nfs_wback_lock(struct rpc_task *task)
        }
 
        /* 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 @@ static void
 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) {
                /*
index 99cdea0e70f3ae696bbbdb105d2c57b467f713cc..08ba2a5d3449fa534f62fffb9a7ad801027bbaf7 100644 (file)
@@ -230,7 +230,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap)
        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 @@ nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset,
 
                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 @@ nfsd_truncate(struct svc_rqst *rqstp, struct svc_fh *fhp, unsigned long size)
        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 @@ nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp)
        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 @@ int
 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 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
        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 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
                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)) {
index 944186e68179408f8d075e51ec342d2b9a75bf44..a2e512d88a03e96d0fd10606844e8032b9d18365 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -69,15 +69,16 @@ asmlinkage int sys_fstatfs(unsigned int fd, struct statfs * buf)
        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 @@ asmlinkage int sys_truncate(const char * path, unsigned long length)
        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 @@ asmlinkage int sys_ftruncate(unsigned int fd, unsigned long length)
                                          length<inode->i_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 @@ asmlinkage int sys_utime(char * filename, struct utimbuf * times)
                    (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 @@ asmlinkage int sys_utimes(char * filename, struct timeval * utimes)
                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 @@ asmlinkage int sys_fchmod(unsigned int fd, mode_t mode)
                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 @@ asmlinkage int sys_chmod(const char * filename, mode_t mode)
                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 @@ static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
                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;
 }
index 0c189dcc33ed474b417b5d63e68d61e4a0599222..0d403f23a47341476ae58563b37815d9626286d8 100644 (file)
@@ -15,8 +15,8 @@
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
 
-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 @@ struct inode_operations proc_link_inode_operations = {
        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 @@ static struct dentry * proc_follow_link(struct inode *inode, struct dentry *base
        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 @@ static struct dentry * proc_follow_link(struct inode *inode, struct dentry *base
        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 @@ static struct dentry * proc_follow_link(struct inode *inode, struct dentry *base
                                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;
index 8c5a1bc3ac0887ed372ec2fe910a0da708faca42..6fdccf97461e54d86d9be3d928ac8a5eb4324dc5 100644 (file)
@@ -65,24 +65,24 @@ struct inode_operations devtree_symlink_inode_operations = {
        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)
index c72c064835f5ed9dfda308a1574b4f5bdd14e537..1c7858a6f7115995ab8f00de709c3127182af74f 100644 (file)
@@ -368,7 +368,7 @@ int proc_unregister(struct proc_dir_entry * dir, int ino)
 /*
  * /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 @@ static int proc_self_readlink(struct inode * inode, char * buffer, int buflen)
        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);
 }      
 
index 3c99d0d9f82201b711379880864e7116c5f11f11..bff93a687ec9d2cbf69883df596ff12be56deb84 100644 (file)
@@ -391,8 +391,9 @@ out:
  */
 
 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 @@ romfs_readpage(struct inode * inode, struct page * page)
 }
 
 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 @@ out:
        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;
 
index 3ad931359b900bc4adcf7c17ef47e56f82ffc90f..6546b5e7d5ae53a43a00b279b6ffe0c4d0417f59 100644 (file)
@@ -89,7 +89,7 @@ dentry->d_parent->d_name.name, dentry->d_name.name, (int) filp->f_pos);
        /*
         * 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 @@ file->f_dentry->d_name.name);
        }
 
        if (server->conn_pid)
-               error = smb_revalidate_inode(dir);
+               error = smb_revalidate_inode(dentry);
        return error;
 }
 
@@ -235,7 +235,7 @@ dentry->d_parent->d_name.name, dentry->d_name.name);
 #endif
                        valid = 0;
                } else if (!valid)
-                       valid = (smb_revalidate_inode(inode) == 0);
+                       valid = (smb_revalidate_inode(dentry) == 0);
        } else
        {
        /*
index c04e0acc05a78614840dc01e4918df8e1c291a17..4c21236ec525c176ff088a997e41c36d0204ee08 100644 (file)
@@ -52,24 +52,17 @@ dentry->d_parent->d_name.name, dentry->d_name.name);
  * 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 @@ io_error:
 }
 
 int
-smb_readpage(struct inode *inode, struct page *page)
+smb_readpage(struct dentry *dentry, struct page *page)
 {
        int             error;
 
@@ -121,7 +114,7 @@ smb_readpage(struct inode *inode, struct page *page)
 #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 @@ smb_readpage(struct inode *inode, struct page *page)
  * 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 @@ smb_writepage_sync(struct inode *inode, struct page *page,
        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 @@ io_error:
  * (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 @@ smb_writepage(struct inode *inode, struct page *page)
 #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 @@ smb_updatepage(struct inode *inode, struct page *page, const char *buffer,
 
        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 @@ static ssize_t
 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 @@ dentry->d_parent->d_name.name, dentry->d_name.name,
 (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 @@ dentry->d_parent->d_name.name, dentry->d_name.name, status);
 
 #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 @@ static int
 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 @@ static ssize_t
 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 @@ dentry->d_parent->d_name.name, dentry->d_name.name, result);
                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:
index 81a338d7c74213de444bf6ce1564f2e87e5f6208..b8b208df0e83209c256a895af858c714228cc91d 100644 (file)
@@ -186,8 +186,9 @@ printk("smb_invalidate_inodes\n");
  * 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 @@ jiffies, inode->u.smbfs_i.oldmtime);
        {
 #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 @@ smb_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
 }
 
 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;
 
index b17c6bb13d52ae669069948163e00d863511dd4b..2b80995c1adfdc84c4ee837cb59aa3628b619a68 100644 (file)
--- a/fs/stat.c
+++ b/fs/stat.c
  * 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 @@ asmlinkage int sys_stat(char * filename, struct __old_kernel_stat * statbuf)
 
        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 @@ asmlinkage int sys_newstat(char * filename, struct stat * statbuf)
 
        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 @@ asmlinkage int sys_lstat(char * filename, struct __old_kernel_stat * statbuf)
 
        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 @@ asmlinkage int sys_newlstat(char * filename, struct stat * statbuf)
 
        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 @@ asmlinkage int sys_fstat(unsigned int fd, struct __old_kernel_stat * statbuf)
        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 @@ asmlinkage int sys_newfstat(unsigned int fd, struct stat * statbuf)
        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 @@ asmlinkage int sys_readlink(const char * path, char * buf, int bufsiz)
                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);
        }
index d84a9524ffc0ea31219a1763c04fc5852dca5542..f9d2c379896a066073b09d0b857ccb7e189517d6 100644 (file)
@@ -873,8 +873,9 @@ void sysv_read_inode(struct inode * inode)
 }
 
 /* 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)
index d76c3fa6611f90541bb306e56bb0eee4b8224c95..2ce56e39008ef8762a4e1761fba6887e72fd22ec 100644 (file)
@@ -20,8 +20,8 @@
 
 #include <asm/uaccess.h>
 
-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 @@ struct inode_operations sysv_symlink_inode_operations = {
        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 @@ static struct dentry *sysv_follow_link(struct inode * inode, struct dentry * bas
        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;
index 76d5fbf113c127cea71f49bdb9b47f56a2bbc560..83ad77d2a098d9f9b115f98be01fe6d57a19941c 100644 (file)
@@ -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 @@ ufs_readlink(struct inode * inode, char * buffer, int buflen)
  * 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;
index 53a2ce3e32d24894af2fbc0142df39397dc441be..d32950c609ae82743b05be87fd9826558c5ab970 100644 (file)
@@ -66,6 +66,7 @@ struct dentry {
        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 @@ struct dentry_operations {
        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
index 6045487983e7783c218f28b5ba540c67d700b617..49cdbe2f5ffe33ad2e6d4df591aa4aa2cea379b8 100644 (file)
@@ -499,9 +499,10 @@ extern int ext2_mkdir (struct inode *,struct dentry *,int);
 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 *, ...)
index 90830685a100534845cd3320820200cd99db485b..1c2320e99efa6ab5e289c65dd5ff508662b40e41 100644 (file)
@@ -571,24 +571,25 @@ struct inode_operations {
        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 @@ struct super_operations {
        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 void kill_fasync(struct fasync_struct *fa, int sig);
 
 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 void sync_dev(kdev_t dev);
 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 struct buffer_head * breada(kdev_t dev,int block, int size,
 
 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 file_fsync(struct file *, struct dentry *dir);
 
 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 <linux/minix_fs.h>
index de0e47ab202cbcc1e3486aca80b16fdd3b749340..3aed2bb1f2b828ae3c63f888c4b2ca36a1b4893f 100644 (file)
@@ -225,7 +225,7 @@ int get_cluster(struct inode *inode,int cluster);
 
 /* 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);
index cf67ca5b4211b7a92022840c627a6e58d16ec839..584b99c960e07685bbedfda8c53633450f0df271 100644 (file)
 
 #include <linux/signal.h>
 #include <linux/sched.h>
-#include <linux/nfs.h>
 #include <linux/in.h>
+
 #include <linux/sunrpc/debug.h>
+#include <linux/nfs.h>
 #include <linux/nfs_mount.h>
 
 /*
  */
 #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 int init_nfs_fs(void);
 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 @@ extern struct inode_operations nfs_file_inode_operations;
  * 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 @@ extern struct inode_operations nfs_symlink_inode_operations;
 /*
  * 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 @@ extern int  nfs_mount(struct sockaddr_in *, char *, struct nfs_fh *);
  * 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;
index b0163ec22c5075cbfb8b0f2e020659f9cb68143b..722a9930dce57fdab48a996264b90fa0cb0a5e7f 100644 (file)
@@ -15,11 +15,6 @@ struct nfs_inode_info {
         */
        struct pipe_inode_info  pipeinfo;
 
-       /*
-        * The file handle
-        */
-       struct nfs_fh           fhandle;
-
        /*
         * Various flags
         */
index f21d6608013026da1c72cc25a82fe0302377d793..eaca428076fcf8283f429faced16ddd3affb1da8 100644 (file)
@@ -94,9 +94,9 @@ int smb_ioctl (struct inode *, struct file *, unsigned int, unsigned long);
 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 *);
 
index b78d34facc2d81153c3e2ed2b1ee1277ae40f9a2..d6218c861e95d92b4a53835831c14187c05ffae4 100644 (file)
@@ -260,8 +260,10 @@ static inline void add_to_page_cache(struct page * page,
  * 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 @@ static unsigned long try_to_read_ahead(struct inode * inode, unsigned long offse
                         */
                        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 @@ static inline int get_max_readahead(struct inode * inode)
        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 @@ static inline unsigned long generic_file_readahead(int reada_ok, struct file * f
        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 @@ static inline unsigned long generic_file_readahead(int reada_ok, struct file * f
 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 @@ no_cached_page:
                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 @@ page_read_error:
                 * 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 @@ page_read_error:
  */
 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 @@ no_cached_page:
        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 @@ page_read_error:
         * 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 @@ ssize_t
 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 @@ page_wait:
                 */
                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 @@ page_wait:
                }
 
                /* 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);