Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag '5.4-rc2-smb3' of git://git.samba.org/sfrench/cifs-2.6

Pull cifs fixes from Steve French:
"Eight small SMB3 fixes, four for stable, and important fix for the
recent regression introduced by filesystem timestamp range patches"

* tag '5.4-rc2-smb3' of git://git.samba.org/sfrench/cifs-2.6:
CIFS: Force reval dentry if LOOKUP_REVAL flag is set
CIFS: Force revalidate inode when dentry is stale
smb3: Fix regression in time handling
smb3: remove noisy debug message and minor cleanup
CIFS: Gracefully handle QueryInfo errors during open
cifs: use cifsInodeInfo->open_file_lock while iterating to avoid a panic
fs: cifs: mute -Wunused-const-variable message
smb3: cleanup some recent endian errors spotted by updated sparse

+58 -41
+17 -9
fs/cifs/cifsfs.c
··· 169 169 else 170 170 sb->s_maxbytes = MAX_NON_LFS; 171 171 172 - /* BB FIXME fix time_gran to be larger for LANMAN sessions */ 173 - sb->s_time_gran = 100; 174 - 175 - if (tcon->unix_ext) { 172 + /* Some very old servers like DOS and OS/2 used 2 second granularity */ 173 + if ((tcon->ses->server->vals->protocol_id == SMB10_PROT_ID) && 174 + ((tcon->ses->capabilities & 175 + tcon->ses->server->vals->cap_nt_find) == 0) && 176 + !tcon->unix_ext) { 177 + sb->s_time_gran = 1000000000; /* 1 second is max allowed gran */ 178 + ts = cnvrtDosUnixTm(cpu_to_le16(SMB_DATE_MIN), 0, 0); 179 + sb->s_time_min = ts.tv_sec; 180 + ts = cnvrtDosUnixTm(cpu_to_le16(SMB_DATE_MAX), 181 + cpu_to_le16(SMB_TIME_MAX), 0); 182 + sb->s_time_max = ts.tv_sec; 183 + } else { 184 + /* 185 + * Almost every server, including all SMB2+, uses DCE TIME 186 + * ie 100 nanosecond units, since 1601. See MS-DTYP and MS-FSCC 187 + */ 188 + sb->s_time_gran = 100; 176 189 ts = cifs_NTtimeToUnix(0); 177 190 sb->s_time_min = ts.tv_sec; 178 191 ts = cifs_NTtimeToUnix(cpu_to_le64(S64_MAX)); 179 - sb->s_time_max = ts.tv_sec; 180 - } else { 181 - ts = cnvrtDosUnixTm(cpu_to_le16(SMB_DATE_MIN), 0, 0); 182 - sb->s_time_min = ts.tv_sec; 183 - ts = cnvrtDosUnixTm(cpu_to_le16(SMB_DATE_MAX), cpu_to_le16(SMB_TIME_MAX), 0); 184 192 sb->s_time_max = ts.tv_sec; 185 193 } 186 194
+1 -1
fs/cifs/cifsglob.h
··· 1210 1210 bool smallBuf:1; /* so we know which buf_release function to call */ 1211 1211 }; 1212 1212 1213 - #define ACL_NO_MODE -1 1213 + #define ACL_NO_MODE ((umode_t)(-1)) 1214 1214 struct cifs_open_parms { 1215 1215 struct cifs_tcon *tcon; 1216 1216 struct cifs_sb_info *cifs_sb;
+2 -2
fs/cifs/connect.c
··· 4264 4264 server->ops->qfs_tcon(*xid, tcon); 4265 4265 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE) { 4266 4266 if (tcon->fsDevInfo.DeviceCharacteristics & 4267 - FILE_READ_ONLY_DEVICE) 4267 + cpu_to_le32(FILE_READ_ONLY_DEVICE)) 4268 4268 cifs_dbg(VFS, "mounted to read only share\n"); 4269 4269 else if ((cifs_sb->mnt_cifs_flags & 4270 4270 CIFS_MOUNT_RW_CACHE) == 0) ··· 4445 4445 int rc; 4446 4446 struct dfs_info3_param ref = {0}; 4447 4447 char *mdata = NULL, *fake_devname = NULL; 4448 - struct smb_vol fake_vol = {0}; 4448 + struct smb_vol fake_vol = {NULL}; 4449 4449 4450 4450 cifs_dbg(FYI, "%s: dfs path: %s\n", __func__, path); 4451 4451
+7 -1
fs/cifs/dir.c
··· 738 738 static int 739 739 cifs_d_revalidate(struct dentry *direntry, unsigned int flags) 740 740 { 741 + struct inode *inode; 742 + 741 743 if (flags & LOOKUP_RCU) 742 744 return -ECHILD; 743 745 744 746 if (d_really_is_positive(direntry)) { 747 + inode = d_inode(direntry); 748 + if ((flags & LOOKUP_REVAL) && !CIFS_CACHE_READ(CIFS_I(inode))) 749 + CIFS_I(inode)->time = 0; /* force reval */ 750 + 745 751 if (cifs_revalidate_dentry(direntry)) 746 752 return 0; 747 753 else { ··· 758 752 * attributes will have been updated by 759 753 * cifs_revalidate_dentry(). 760 754 */ 761 - if (IS_AUTOMOUNT(d_inode(direntry)) && 755 + if (IS_AUTOMOUNT(inode) && 762 756 !(direntry->d_flags & DCACHE_NEED_AUTOMOUNT)) { 763 757 spin_lock(&direntry->d_lock); 764 758 direntry->d_flags |= DCACHE_NEED_AUTOMOUNT;
+17 -16
fs/cifs/file.c
··· 253 253 rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb, 254 254 xid, fid); 255 255 256 + if (rc) { 257 + server->ops->close(xid, tcon, fid); 258 + if (rc == -ESTALE) 259 + rc = -EOPENSTALE; 260 + } 261 + 256 262 out: 257 263 kfree(buf); 258 264 return rc; ··· 1846 1840 { 1847 1841 struct cifsFileInfo *open_file = NULL; 1848 1842 struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb); 1849 - struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); 1850 1843 1851 1844 /* only filter by fsuid on multiuser mounts */ 1852 1845 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) 1853 1846 fsuid_only = false; 1854 1847 1855 - spin_lock(&tcon->open_file_lock); 1848 + spin_lock(&cifs_inode->open_file_lock); 1856 1849 /* we could simply get the first_list_entry since write-only entries 1857 1850 are always at the end of the list but since the first entry might 1858 1851 have a close pending, we go through the whole list */ ··· 1863 1858 /* found a good file */ 1864 1859 /* lock it so it will not be closed on us */ 1865 1860 cifsFileInfo_get(open_file); 1866 - spin_unlock(&tcon->open_file_lock); 1861 + spin_unlock(&cifs_inode->open_file_lock); 1867 1862 return open_file; 1868 1863 } /* else might as well continue, and look for 1869 1864 another, or simply have the caller reopen it ··· 1871 1866 } else /* write only file */ 1872 1867 break; /* write only files are last so must be done */ 1873 1868 } 1874 - spin_unlock(&tcon->open_file_lock); 1869 + spin_unlock(&cifs_inode->open_file_lock); 1875 1870 return NULL; 1876 1871 } 1877 1872 ··· 1882 1877 { 1883 1878 struct cifsFileInfo *open_file, *inv_file = NULL; 1884 1879 struct cifs_sb_info *cifs_sb; 1885 - struct cifs_tcon *tcon; 1886 1880 bool any_available = false; 1887 1881 int rc = -EBADF; 1888 1882 unsigned int refind = 0; ··· 1901 1897 } 1902 1898 1903 1899 cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb); 1904 - tcon = cifs_sb_master_tcon(cifs_sb); 1905 1900 1906 1901 /* only filter by fsuid on multiuser mounts */ 1907 1902 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) 1908 1903 fsuid_only = false; 1909 1904 1910 - spin_lock(&tcon->open_file_lock); 1905 + spin_lock(&cifs_inode->open_file_lock); 1911 1906 refind_writable: 1912 1907 if (refind > MAX_REOPEN_ATT) { 1913 - spin_unlock(&tcon->open_file_lock); 1908 + spin_unlock(&cifs_inode->open_file_lock); 1914 1909 return rc; 1915 1910 } 1916 1911 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { ··· 1921 1918 if (!open_file->invalidHandle) { 1922 1919 /* found a good writable file */ 1923 1920 cifsFileInfo_get(open_file); 1924 - spin_unlock(&tcon->open_file_lock); 1921 + spin_unlock(&cifs_inode->open_file_lock); 1925 1922 *ret_file = open_file; 1926 1923 return 0; 1927 1924 } else { ··· 1941 1938 cifsFileInfo_get(inv_file); 1942 1939 } 1943 1940 1944 - spin_unlock(&tcon->open_file_lock); 1941 + spin_unlock(&cifs_inode->open_file_lock); 1945 1942 1946 1943 if (inv_file) { 1947 1944 rc = cifs_reopen_file(inv_file, false); ··· 1956 1953 cifsFileInfo_put(inv_file); 1957 1954 ++refind; 1958 1955 inv_file = NULL; 1959 - spin_lock(&tcon->open_file_lock); 1956 + spin_lock(&cifs_inode->open_file_lock); 1960 1957 goto refind_writable; 1961 1958 } 1962 1959 ··· 4464 4461 static int is_inode_writable(struct cifsInodeInfo *cifs_inode) 4465 4462 { 4466 4463 struct cifsFileInfo *open_file; 4467 - struct cifs_tcon *tcon = 4468 - cifs_sb_master_tcon(CIFS_SB(cifs_inode->vfs_inode.i_sb)); 4469 4464 4470 - spin_lock(&tcon->open_file_lock); 4465 + spin_lock(&cifs_inode->open_file_lock); 4471 4466 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { 4472 4467 if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) { 4473 - spin_unlock(&tcon->open_file_lock); 4468 + spin_unlock(&cifs_inode->open_file_lock); 4474 4469 return 1; 4475 4470 } 4476 4471 } 4477 - spin_unlock(&tcon->open_file_lock); 4472 + spin_unlock(&cifs_inode->open_file_lock); 4478 4473 return 0; 4479 4474 } 4480 4475
+4
fs/cifs/inode.c
··· 414 414 /* if uniqueid is different, return error */ 415 415 if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM && 416 416 CIFS_I(*pinode)->uniqueid != fattr.cf_uniqueid)) { 417 + CIFS_I(*pinode)->time = 0; /* force reval */ 417 418 rc = -ESTALE; 418 419 goto cgiiu_exit; 419 420 } ··· 422 421 /* if filetype is different, return error */ 423 422 if (unlikely(((*pinode)->i_mode & S_IFMT) != 424 423 (fattr.cf_mode & S_IFMT))) { 424 + CIFS_I(*pinode)->time = 0; /* force reval */ 425 425 rc = -ESTALE; 426 426 goto cgiiu_exit; 427 427 } ··· 935 933 /* if uniqueid is different, return error */ 936 934 if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM && 937 935 CIFS_I(*inode)->uniqueid != fattr.cf_uniqueid)) { 936 + CIFS_I(*inode)->time = 0; /* force reval */ 938 937 rc = -ESTALE; 939 938 goto cgii_exit; 940 939 } ··· 943 940 /* if filetype is different, return error */ 944 941 if (unlikely(((*inode)->i_mode & S_IFMT) != 945 942 (fattr.cf_mode & S_IFMT))) { 943 + CIFS_I(*inode)->time = 0; /* force reval */ 946 944 rc = -ESTALE; 947 945 goto cgii_exit; 948 946 }
-4
fs/cifs/netmisc.c
··· 117 117 {0, 0} 118 118 }; 119 119 120 - static const struct smb_to_posix_error mapping_table_ERRHRD[] = { 121 - {0, 0} 122 - }; 123 - 124 120 /* 125 121 * Convert a string containing text IPv4 or IPv6 address to binary form. 126 122 *
+6 -8
fs/cifs/smb2pdu.c
··· 751 751 unsigned int num = *num_iovec; 752 752 753 753 iov[num].iov_base = create_posix_buf(mode); 754 - if (mode == -1) 755 - cifs_dbg(VFS, "illegal mode\n"); /* BB REMOVEME */ 754 + if (mode == ACL_NO_MODE) 755 + cifs_dbg(FYI, "illegal mode\n"); 756 756 if (iov[num].iov_base == NULL) 757 757 return -ENOMEM; 758 758 iov[num].iov_len = sizeof(struct create_posix); ··· 2521 2521 return rc; 2522 2522 } 2523 2523 2524 - /* TODO: add handling for the mode on create */ 2525 - if (oparms->disposition == FILE_CREATE) 2526 - cifs_dbg(VFS, "mode is 0x%x\n", oparms->mode); /* BB REMOVEME */ 2527 - 2528 - if ((oparms->disposition == FILE_CREATE) && (oparms->mode != -1)) { 2524 + if ((oparms->disposition == FILE_CREATE) && 2525 + (oparms->mode != ACL_NO_MODE)) { 2529 2526 if (n_iov > 2) { 2530 2527 struct create_context *ccontext = 2531 2528 (struct create_context *)iov[n_iov-1].iov_base; ··· 3214 3217 3215 3218 req->PersistentFileId = persistent_fid; 3216 3219 req->VolatileFileId = volatile_fid; 3217 - req->OutputBufferLength = SMB2_MAX_BUFFER_SIZE - MAX_SMB2_HDR_SIZE; 3220 + req->OutputBufferLength = 3221 + cpu_to_le32(SMB2_MAX_BUFFER_SIZE - MAX_SMB2_HDR_SIZE); 3218 3222 req->CompletionFilter = cpu_to_le32(completion_filter); 3219 3223 if (watch_tree) 3220 3224 req->Flags = cpu_to_le16(SMB2_WATCH_TREE);
+4
fs/cifs/smb2proto.h
··· 150 150 bool is_fsctl, char *in_data, u32 indatalen, 151 151 __u32 max_response_size); 152 152 extern void SMB2_ioctl_free(struct smb_rqst *rqst); 153 + extern int SMB2_change_notify(const unsigned int xid, struct cifs_tcon *tcon, 154 + u64 persistent_fid, u64 volatile_fid, bool watch_tree, 155 + u32 completion_filter); 156 + 153 157 extern int SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, 154 158 u64 persistent_file_id, u64 volatile_file_id); 155 159 extern int SMB2_close_flags(const unsigned int xid, struct cifs_tcon *tcon,