On Thu, Feb 9, 2012 at 12:08 PM, Pavel Shilovsky <piastry@xxxxxxxxxxx> wrote: > Currently we do inc_nlink/drop_nlink for a parent directory for every > mkdir and rmdir calls. That's wrong when POSIX extensions are disabled > because in this case a server doesn't do the same things and returns > the old value on the next QueryInfo request. As the result, we update > our value with the server one and then decrement it on every rmdir > call - go to negative nlink values. > > Fix this by doing inc_nlink/drop_nlink for parent directory in mkdir > and rmdir in POSIX case only. Also add cERROR when nlink value <= 2 > and we still try to decrement it (possible broken servers). > > Signed-off-by: Pavel Shilovsky <piastry@xxxxxxxxxxx> > --- > fs/cifs/inode.c | 14 ++++++++++---- > 1 files changed, 10 insertions(+), 4 deletions(-) > > diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c > index a5f54b7..9af6ec7 100644 > --- a/fs/cifs/inode.c > +++ b/fs/cifs/inode.c > @@ -1355,11 +1355,11 @@ mkdir_retry_old: > d_drop(direntry); > } else { > mkdir_get_info: > - inc_nlink(inode); > - if (pTcon->unix_ext) > + if (pTcon->unix_ext) { > + inc_nlink(inode); > rc = cifs_get_inode_info_unix(&newinode, full_path, > inode->i_sb, xid); > - else > + } else > rc = cifs_get_inode_info(&newinode, full_path, NULL, > inode->i_sb, xid, NULL); > > @@ -1475,7 +1475,13 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) > cifs_put_tlink(tlink); > > if (!rc) { > - drop_nlink(inode); > + if (pTcon->unix_ext) { > + if (inode->i_nlink > 2) > + drop_nlink(inode); > + else > + cERROR(1, "%s: unexpected nlink number(%u)", > + __func__, inode->i_nlink); > + } > spin_lock(&direntry->d_inode->i_lock); > i_size_write(direntry->d_inode, 0); > clear_nlink(direntry->d_inode); > -- > 1.7.1 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-cifs" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html Then we need to apply the same logic to set_nlink() calls and wherever we access i_nlink field also? -- To unsubscribe from this list: send the line "unsubscribe linux-cifs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html