diff options
author | Steve French <sfrench@us.ibm.com> | 2010-05-14 02:19:32 +0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2010-05-14 02:19:32 +0400 |
commit | baa456331738b4e76a92318b62b354377a30ad80 (patch) | |
tree | 75c828a7c8a9f1b5f7f41b2e53271eafb7e561ef /fs/cifs/inode.c | |
parent | aa3e5572c538d753dce11bf93532a75f95d22b40 (diff) | |
parent | 4462dc02842698f173f518c1f5ce79c0fb89395a (diff) | |
download | linux-baa456331738b4e76a92318b62b354377a30ad80.tar.xz |
Merge branch 'master' of /pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
fs/cifs/inode.c
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r-- | fs/cifs/inode.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index b35cb031c20c..5b042fc46450 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -715,6 +715,16 @@ cifs_find_inode(struct inode *inode, void *opaque) if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid) return 0; + /* + * uh oh -- it's a directory. We can't use it since hardlinked dirs are + * verboten. Disable serverino and return it as if it were found, the + * caller can discard it, generate a uniqueid and retry the find + */ + if (S_ISDIR(inode->i_mode) && !list_empty(&inode->i_dentry)) { + fattr->cf_flags |= CIFS_FATTR_INO_COLLISION; + cifs_autodisable_serverino(CIFS_SB(inode->i_sb)); + } + return 1; } @@ -734,15 +744,22 @@ cifs_iget(struct super_block *sb, struct cifs_fattr *fattr) unsigned long hash; struct inode *inode; +retry_iget5_locked: cFYI(1, "looking for uniqueid=%llu", fattr->cf_uniqueid); /* hash down to 32-bits on 32-bit arch */ hash = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid); inode = iget5_locked(sb, hash, cifs_find_inode, cifs_init_inode, fattr); - - /* we have fattrs in hand, update the inode */ if (inode) { + /* was there a problematic inode number collision? */ + if (fattr->cf_flags & CIFS_FATTR_INO_COLLISION) { + iput(inode); + fattr->cf_uniqueid = iunique(sb, ROOT_I); + fattr->cf_flags &= ~CIFS_FATTR_INO_COLLISION; + goto retry_iget5_locked; + } + cifs_fattr_to_inode(inode, fattr); if (sb->s_flags & MS_NOATIME) inode->i_flags |= S_NOATIME | S_NOCMTIME; |