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/