Hello

Enough details in the ChangeLog I hope.

Patch vs 2.4.2-ac12 but appears to be clean vs 2.4.3-pre2 and the recently
released -ac13. Please apply.

/Urban


diff -urN -X exclude linux-2.4.2-ac12-orig/fs/smbfs/ChangeLog 
linux-2.4.2-ac12-smbfs/fs/smbfs/ChangeLog
--- linux-2.4.2-ac12-orig/fs/smbfs/ChangeLog    Thu Feb 22 20:52:03 2001
+++ linux-2.4.2-ac12-smbfs/fs/smbfs/ChangeLog   Tue Mar  6 23:50:06 2001
@@ -1,9 +1,22 @@
 ChangeLog for smbfs.
 
+2001-03-06 Urban Widmark <[EMAIL PROTECTED]>
+
+       * cache.c: d_add on hashed dentries corrupts d_hash list and
+         causes loops in d_lookup. Inherited bug. :)
+       * inode.c: tail -f fix for non-readonly opened files
+         (related to the smb_proc_open change).
+       * inode.c: tail -f fix for fast size changes with the same mtime.
+
+2001-03-02 Michael Kockelkorn <[EMAIL PROTECTED]>
+
+       * proc.c: fix smb_proc_open to allow open being called more than once
+         with different modes (O_RDONLY -> O_WRONLY) without closing.
+
 2001-02-10 Urban Widmark <[EMAIL PROTECTED]>
 
-       * dir.c: replace non-bigmem safe cache with cache code from ncpfs
-         and fix some other bigmem bugs in smbfs.
+       * dir.c, cache.c: replace non-bigmem safe cache with cache code
+         from ncpfs and fix some other bigmem bugs in smbfs.
        * inode.c: root dentry not properly initialized
        * proc.c, sock.c: adjust max parameters & max data to follow max_xmit
          lots of servers were having find_next trouble with this.
diff -urN -X exclude linux-2.4.2-ac12-orig/fs/smbfs/cache.c 
linux-2.4.2-ac12-smbfs/fs/smbfs/cache.c
--- linux-2.4.2-ac12-orig/fs/smbfs/cache.c      Thu Feb 22 20:52:03 2001
+++ linux-2.4.2-ac12-smbfs/fs/smbfs/cache.c     Tue Mar  6 23:01:17 2001
@@ -167,6 +167,7 @@
        struct inode *newino, *inode = dentry->d_inode;
        struct smb_cache_control ctl = *ctrl;
        int valid = 0;
+       int hashed = 0;
        ino_t ino = 0;
 
        qname->hash = full_name_hash(qname->name, qname->len);
@@ -181,9 +182,11 @@
                newdent = d_alloc(dentry, qname);
                if (!newdent)
                        goto end_advance;
-       } else
+       } else {
+               hashed = 1;
                memcpy((char *) newdent->d_name.name, qname->name,
                       newdent->d_name.len);
+       }
 
        if (!newdent->d_inode) {
                smb_renew_times(newdent);
@@ -191,7 +194,9 @@
                newino = smb_iget(inode->i_sb, entry);
                if (newino) {
                        smb_new_dentry(newdent);
-                       d_add(newdent, newino);
+                       d_instantiate(newdent, newino);
+                       if (!hashed)
+                               d_rehash(newdent);
                }
        } else
                smb_set_inode_attr(newdent->d_inode, entry);
diff -urN -X exclude linux-2.4.2-ac12-orig/fs/smbfs/inode.c 
linux-2.4.2-ac12-smbfs/fs/smbfs/inode.c
--- linux-2.4.2-ac12-orig/fs/smbfs/inode.c      Tue Mar  6 21:14:31 2001
+++ linux-2.4.2-ac12-smbfs/fs/smbfs/inode.c     Tue Mar  6 23:05:50 2001
@@ -161,17 +161,15 @@
        struct smb_fattr fattr;
 
        error = smb_proc_getattr(dentry, &fattr);
-       if (!error)
-       {
+       if (!error) {
                smb_renew_times(dentry);
                /*
                 * Check whether the type part of the mode changed,
                 * and don't update the attributes if it did.
                 */
-               if ((inode->i_mode & S_IFMT) == (fattr.f_mode & S_IFMT))
+               if ((inode->i_mode & S_IFMT) == (fattr.f_mode & S_IFMT)) {
                        smb_set_inode_attr(inode, &fattr);
-               else
-               {
+               } else {
                        /*
                         * Big trouble! The inode has become a new object,
                         * so any operations attempted on it are invalid.
@@ -212,18 +210,11 @@
        struct smb_sb_info *s = server_from_dentry(dentry);
        struct inode *inode = dentry->d_inode;
        time_t last_time;
+       loff_t last_sz;
        int error = 0;
 
        DEBUG1("smb_revalidate_inode\n");
-       /*
-        * If this is a file opened with write permissions,
-        * the inode will be up-to-date.
-        */
        lock_kernel();
-       if (S_ISREG(inode->i_mode) && smb_is_open(inode)) {
-               if (inode->u.smbfs_i.access != SMB_O_RDONLY)
-                       goto out;
-       }
 
        /*
         * Check whether we've recently refreshed the inode.
@@ -236,11 +227,13 @@
 
        /*
         * Save the last modified time, then refresh the inode.
-        * (Note: a size change should have a different mtime.)
+        * (Note: a size change should have a different mtime,
+        *  or same mtime but different size.)
         */
        last_time = inode->i_mtime;
+       last_sz   = inode->i_size;
        error = smb_refresh_inode(dentry);
-       if (error || inode->i_mtime != last_time) {
+       if (error || inode->i_mtime != last_time || inode->i_size != last_sz) {
                VERBOSE("%s/%s changed, old=%ld, new=%ld\n",
                        DENTRY_PATH(dentry),
                        (long) last_time, (long) inode->i_mtime);
diff -urN -X exclude linux-2.4.2-ac12-orig/fs/smbfs/proc.c 
linux-2.4.2-ac12-smbfs/fs/smbfs/proc.c
--- linux-2.4.2-ac12-orig/fs/smbfs/proc.c       Tue Mar  6 21:14:31 2001
+++ linux-2.4.2-ac12-smbfs/fs/smbfs/proc.c      Tue Mar  6 23:07:39 2001
@@ -950,7 +950,10 @@
 #if 0
        /* FIXME: why is this code not in? below we fix it so that a caller
           wanting RO doesn't get RW. smb_revalidate_inode does some 
-          optimization based on access mode. tail -f needs it to be correct. */
+          optimization based on access mode. tail -f needs it to be correct.
+
+          We must open rw since we don't do the open if called a second time
+          with different 'wish'. Is that not supported by smb servers? */
        if (!(wish & (O_WRONLY | O_RDWR)))
                mode = read_only;
 #endif
@@ -989,8 +992,6 @@
        /* smb_vwv2 has mtime */
        /* smb_vwv4 has size  */
        ino->u.smbfs_i.access = (WVAL(server->packet, smb_vwv6) & SMB_ACCMASK);
-       if (!(wish & (O_WRONLY | O_RDWR)))
-               ino->u.smbfs_i.access = SMB_O_RDONLY;
        ino->u.smbfs_i.open = server->generation;
 
 out:
@@ -1008,23 +1009,20 @@
        int result;
 
        result = -ENOENT;
-       if (!inode)
-       {
+       if (!inode) {
                printk(KERN_ERR "smb_open: no inode for dentry %s/%s\n",
                       DENTRY_PATH(dentry));
                goto out;
        }
 
-       if (!smb_is_open(inode))
-       {
+       if (!smb_is_open(inode)) {
                struct smb_sb_info *server = SMB_SERVER(inode);
                smb_lock_server(server);
                result = 0;
                if (!smb_is_open(inode))
                        result = smb_proc_open(server, dentry, wish);
                smb_unlock_server(server);
-               if (result)
-               {
+               if (result) {
                        PARANOIA("%s/%s open failed, result=%d\n",
                                 DENTRY_PATH(dentry), result);
                        goto out;

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to