[patch] smbfs: d_add + re-open fixes

2001-03-06 Thread Urban Widmark


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/ChangeLogThu 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, );
-   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, );
-   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 != 

[patch] smbfs: d_add + re-open fixes

2001-03-06 Thread Urban Widmark


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/ChangeLogThu 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