Loading fs/cifs/CHANGES +5 −0 Original line number Original line Diff line number Diff line Version 1.37 ------------ Fix readdir caching when unlink removes file in current search buffer, and this is followed by a rewind search to just before the deleted entry. Version 1.36 Version 1.36 ------------ ------------ Add support for mounting to older pre-CIFS servers such as Windows9x and ME. Add support for mounting to older pre-CIFS servers such as Windows9x and ME. Loading fs/cifs/cifsfs.h +1 −1 Original line number Original line Diff line number Diff line Loading @@ -97,5 +97,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); extern int cifs_ioctl (struct inode * inode, struct file * filep, extern int cifs_ioctl (struct inode * inode, struct file * filep, unsigned int command, unsigned long arg); unsigned int command, unsigned long arg); #define CIFS_VERSION "1.36" #define CIFS_VERSION "1.37" #endif /* _CIFSFS_H */ #endif /* _CIFSFS_H */ fs/cifs/readdir.c +32 −5 Original line number Original line Diff line number Diff line Loading @@ -396,7 +396,8 @@ static int initiate_cifs_search(const int xid, struct file *file) rc = CIFSFindFirst(xid, pTcon,full_path,cifs_sb->local_nls, rc = CIFSFindFirst(xid, pTcon,full_path,cifs_sb->local_nls, &cifsFile->netfid, &cifsFile->srch_inf, &cifsFile->netfid, &cifsFile->srch_inf, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb)); cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb)); if(rc == 0) if(rc == 0) cifsFile->invalidHandle = FALSE; cifsFile->invalidHandle = FALSE; if((rc == -EOPNOTSUPP) && if((rc == -EOPNOTSUPP) && Loading Loading @@ -513,6 +514,30 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile) return rc; return rc; } } /* Check if directory that we are searching has changed so we can decide whether we can use the cached search results from the previous search */ static int is_dir_changed(struct file * file) { struct inode * inode; struct cifsInodeInfo *cifsInfo; if(file->f_dentry == NULL) return 0; inode = file->f_dentry->d_inode; if(inode == NULL) return 0; cifsInfo = CIFS_I(inode); if(cifsInfo->time == 0) return 1; /* directory was changed, perhaps due to unlink */ else return 0; } /* find the corresponding entry in the search */ /* find the corresponding entry in the search */ /* Note that the SMB server returns search entries for . and .. which /* Note that the SMB server returns search entries for . and .. which complicates logic here if we choose to parse for them and we do not complicates logic here if we choose to parse for them and we do not Loading @@ -529,7 +554,8 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, struct cifsFileInfo * cifsFile = file->private_data; struct cifsFileInfo * cifsFile = file->private_data; /* check if index in the buffer */ /* check if index in the buffer */ if((cifsFile == NULL) || (ppCurrentEntry == NULL) || (num_to_ret == NULL)) if((cifsFile == NULL) || (ppCurrentEntry == NULL) || (num_to_ret == NULL)) return -ENOENT; return -ENOENT; *ppCurrentEntry = NULL; *ppCurrentEntry = NULL; Loading @@ -537,7 +563,9 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, cifsFile->srch_inf.index_of_last_entry - cifsFile->srch_inf.index_of_last_entry - cifsFile->srch_inf.entries_in_buffer; cifsFile->srch_inf.entries_in_buffer; /* dump_cifs_file_struct(file, "In fce ");*/ /* dump_cifs_file_struct(file, "In fce ");*/ if(index_to_find < first_entry_in_buffer) { if(((index_to_find < cifsFile->srch_inf.index_of_last_entry) && is_dir_changed(file)) || (index_to_find < first_entry_in_buffer)) { /* close and restart search */ /* close and restart search */ cFYI(1,("search backing up - close and restart search")); cFYI(1,("search backing up - close and restart search")); cifsFile->invalidHandle = TRUE; cifsFile->invalidHandle = TRUE; Loading Loading @@ -604,7 +632,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, } } if(pos_in_buf >= cifsFile->srch_inf.entries_in_buffer) { if(pos_in_buf >= cifsFile->srch_inf.entries_in_buffer) { cFYI(1,("can not return entries when pos_in_buf beyond last entry")); cFYI(1,("can not return entries pos_in_buf beyond last entry")); *num_to_ret = 0; *num_to_ret = 0; } else } else *num_to_ret = cifsFile->srch_inf.entries_in_buffer - pos_in_buf; *num_to_ret = cifsFile->srch_inf.entries_in_buffer - pos_in_buf; Loading Loading @@ -833,7 +861,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) if(pTcon == NULL) if(pTcon == NULL) return -EINVAL; return -EINVAL; switch ((int) file->f_pos) { switch ((int) file->f_pos) { case 0: case 0: /*if (filldir(direntry, ".", 1, file->f_pos, /*if (filldir(direntry, ".", 1, file->f_pos, Loading Loading
fs/cifs/CHANGES +5 −0 Original line number Original line Diff line number Diff line Version 1.37 ------------ Fix readdir caching when unlink removes file in current search buffer, and this is followed by a rewind search to just before the deleted entry. Version 1.36 Version 1.36 ------------ ------------ Add support for mounting to older pre-CIFS servers such as Windows9x and ME. Add support for mounting to older pre-CIFS servers such as Windows9x and ME. Loading
fs/cifs/cifsfs.h +1 −1 Original line number Original line Diff line number Diff line Loading @@ -97,5 +97,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); extern int cifs_ioctl (struct inode * inode, struct file * filep, extern int cifs_ioctl (struct inode * inode, struct file * filep, unsigned int command, unsigned long arg); unsigned int command, unsigned long arg); #define CIFS_VERSION "1.36" #define CIFS_VERSION "1.37" #endif /* _CIFSFS_H */ #endif /* _CIFSFS_H */
fs/cifs/readdir.c +32 −5 Original line number Original line Diff line number Diff line Loading @@ -396,7 +396,8 @@ static int initiate_cifs_search(const int xid, struct file *file) rc = CIFSFindFirst(xid, pTcon,full_path,cifs_sb->local_nls, rc = CIFSFindFirst(xid, pTcon,full_path,cifs_sb->local_nls, &cifsFile->netfid, &cifsFile->srch_inf, &cifsFile->netfid, &cifsFile->srch_inf, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb)); cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb)); if(rc == 0) if(rc == 0) cifsFile->invalidHandle = FALSE; cifsFile->invalidHandle = FALSE; if((rc == -EOPNOTSUPP) && if((rc == -EOPNOTSUPP) && Loading Loading @@ -513,6 +514,30 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile) return rc; return rc; } } /* Check if directory that we are searching has changed so we can decide whether we can use the cached search results from the previous search */ static int is_dir_changed(struct file * file) { struct inode * inode; struct cifsInodeInfo *cifsInfo; if(file->f_dentry == NULL) return 0; inode = file->f_dentry->d_inode; if(inode == NULL) return 0; cifsInfo = CIFS_I(inode); if(cifsInfo->time == 0) return 1; /* directory was changed, perhaps due to unlink */ else return 0; } /* find the corresponding entry in the search */ /* find the corresponding entry in the search */ /* Note that the SMB server returns search entries for . and .. which /* Note that the SMB server returns search entries for . and .. which complicates logic here if we choose to parse for them and we do not complicates logic here if we choose to parse for them and we do not Loading @@ -529,7 +554,8 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, struct cifsFileInfo * cifsFile = file->private_data; struct cifsFileInfo * cifsFile = file->private_data; /* check if index in the buffer */ /* check if index in the buffer */ if((cifsFile == NULL) || (ppCurrentEntry == NULL) || (num_to_ret == NULL)) if((cifsFile == NULL) || (ppCurrentEntry == NULL) || (num_to_ret == NULL)) return -ENOENT; return -ENOENT; *ppCurrentEntry = NULL; *ppCurrentEntry = NULL; Loading @@ -537,7 +563,9 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, cifsFile->srch_inf.index_of_last_entry - cifsFile->srch_inf.index_of_last_entry - cifsFile->srch_inf.entries_in_buffer; cifsFile->srch_inf.entries_in_buffer; /* dump_cifs_file_struct(file, "In fce ");*/ /* dump_cifs_file_struct(file, "In fce ");*/ if(index_to_find < first_entry_in_buffer) { if(((index_to_find < cifsFile->srch_inf.index_of_last_entry) && is_dir_changed(file)) || (index_to_find < first_entry_in_buffer)) { /* close and restart search */ /* close and restart search */ cFYI(1,("search backing up - close and restart search")); cFYI(1,("search backing up - close and restart search")); cifsFile->invalidHandle = TRUE; cifsFile->invalidHandle = TRUE; Loading Loading @@ -604,7 +632,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, } } if(pos_in_buf >= cifsFile->srch_inf.entries_in_buffer) { if(pos_in_buf >= cifsFile->srch_inf.entries_in_buffer) { cFYI(1,("can not return entries when pos_in_buf beyond last entry")); cFYI(1,("can not return entries pos_in_buf beyond last entry")); *num_to_ret = 0; *num_to_ret = 0; } else } else *num_to_ret = cifsFile->srch_inf.entries_in_buffer - pos_in_buf; *num_to_ret = cifsFile->srch_inf.entries_in_buffer - pos_in_buf; Loading Loading @@ -833,7 +861,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) if(pTcon == NULL) if(pTcon == NULL) return -EINVAL; return -EINVAL; switch ((int) file->f_pos) { switch ((int) file->f_pos) { case 0: case 0: /*if (filldir(direntry, ".", 1, file->f_pos, /*if (filldir(direntry, ".", 1, file->f_pos, Loading