From 31ec35d6c81175016a6372571eab23b6bd40b406 Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 16 Nov 2006 20:54:20 +0000 Subject: [CIFS] Incorrect hardlink count when original file is cached (oplocked) Fixes Samba bug 2823 In this case hardlink count is stale for one of the two inodes (ie the original file) until it is closed - since revalidate does not go to server while file is cached locally. Signed-off-by: Steve French --- fs/cifs/link.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) (limited to 'fs') diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 0bee8b7e521a..8e259969354b 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c @@ -69,17 +69,30 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode, rc = -EOPNOTSUPP; } -/* if (!rc) */ - { - /* renew_parental_timestamps(old_file); - inode->i_nlink++; - mark_inode_dirty(inode); - d_instantiate(direntry, inode); */ - /* BB add call to either mark inode dirty or refresh its data and timestamp to current time */ + d_drop(direntry); /* force new lookup from server of target */ + + /* if source file is cached (oplocked) revalidate will not go to server + until the file is closed or oplock broken so update nlinks locally */ + if(old_file->d_inode) { + cifsInode = CIFS_I(old_file->d_inode); + if(rc == 0) { + old_file->d_inode->i_nlink++; + old_file->d_inode->i_ctime = CURRENT_TIME; + /* parent dir timestamps will update from srv + within a second, would it really be worth it + to set the parent dir cifs inode time to zero + to force revalidate (faster) for it too? */ + } + /* if not oplocked will force revalidate to get info + on source file from srv */ + cifsInode->time = 0; + + /* Will update parent dir timestamps from srv within a second. + Would it really be worth it to set the parent dir (cifs + inode) time field to zero to force revalidate on parent + directory faster ie + CIFS_I(inode)->time = 0; */ } - d_drop(direntry); /* force new lookup from server */ - cifsInode = CIFS_I(old_file->d_inode); - cifsInode->time = 0; /* will force revalidate to go get info when needed */ cifs_hl_exit: kfree(fromName); -- cgit v1.2.3 From 8d6286fdfd290589f8446ec1503702227263dcfd Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 16 Nov 2006 22:48:25 +0000 Subject: [CIFS] Fix timezone handling on stat to os/2 We were adjusting for timezone on readdir but not on stat Signed-off-by: Steve French --- fs/cifs/inode.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'fs') diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 1ad8c9fcc742..c4fa91b8b62f 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -318,6 +318,7 @@ int cifs_get_inode_info(struct inode **pinode, struct cifs_sb_info *cifs_sb = CIFS_SB(sb); char *tmp_path; char *buf = NULL; + int adjustTZ = FALSE; pTcon = cifs_sb->tcon; cFYI(1,("Getting info on %s", search_path)); @@ -348,6 +349,7 @@ int cifs_get_inode_info(struct inode **pinode, pfindData, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); + adjustTZ = TRUE; } } @@ -444,6 +446,10 @@ int cifs_get_inode_info(struct inode **pinode, inode->i_ctime = cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); cFYI(0, ("Attributes came in as 0x%x", attr)); + if(adjustTZ && (pTcon->ses) && (pTcon->ses->server)) { + inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj; + inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj; + } /* set default mode. will override for dirs below */ if (atomic_read(&cifsInfo->inUse) == 0) -- cgit v1.2.3