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

cifs: smb1: Try failing back to SetFileInfo if SetPathInfo fails

RHBZ 1145308

Some very old server may not support SetPathInfo to adjust the timestamps
of directories. For these servers, try to open the directory and use SetFileInfo.

Minor correction to patch included that was
Reported-by: kernel test robot <lkp@intel.com>

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Tested-by: Kenneth D'souza <kdsouza@redhat.com>

authored by

Ronnie Sahlberg and committed by
Steve French
8e408fc9 a3713ec3

+41 -4
+1 -1
fs/cifs/cifsproto.h
··· 345 345 extern int CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon, 346 346 const char *fileName, const FILE_BASIC_INFO *data, 347 347 const struct nls_table *nls_codepage, 348 - int remap_special_chars); 348 + struct cifs_sb_info *cifs_sb); 349 349 extern int CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon, 350 350 const FILE_BASIC_INFO *data, __u16 fid, 351 351 __u32 pid_of_opener);
+38 -1
fs/cifs/cifssmb.c
··· 5913 5913 return rc; 5914 5914 } 5915 5915 5916 + static int 5917 + CIFSSMBSetPathInfoFB(const unsigned int xid, struct cifs_tcon *tcon, 5918 + const char *fileName, const FILE_BASIC_INFO *data, 5919 + const struct nls_table *nls_codepage, 5920 + struct cifs_sb_info *cifs_sb) 5921 + { 5922 + int oplock = 0; 5923 + struct cifs_open_parms oparms; 5924 + struct cifs_fid fid; 5925 + int rc; 5926 + 5927 + oparms.tcon = tcon; 5928 + oparms.cifs_sb = cifs_sb; 5929 + oparms.desired_access = GENERIC_WRITE; 5930 + oparms.create_options = cifs_create_options(cifs_sb, 0); 5931 + oparms.disposition = FILE_OPEN; 5932 + oparms.path = fileName; 5933 + oparms.fid = &fid; 5934 + oparms.reconnect = false; 5935 + 5936 + rc = CIFS_open(xid, &oparms, &oplock, NULL); 5937 + if (rc) 5938 + goto out; 5939 + 5940 + rc = CIFSSMBSetFileInfo(xid, tcon, data, fid.netfid, current->tgid); 5941 + CIFSSMBClose(xid, tcon, fid.netfid); 5942 + out: 5943 + 5944 + return rc; 5945 + } 5946 + 5916 5947 int 5917 5948 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon, 5918 5949 const char *fileName, const FILE_BASIC_INFO *data, 5919 - const struct nls_table *nls_codepage, int remap) 5950 + const struct nls_table *nls_codepage, 5951 + struct cifs_sb_info *cifs_sb) 5920 5952 { 5921 5953 TRANSACTION2_SPI_REQ *pSMB = NULL; 5922 5954 TRANSACTION2_SPI_RSP *pSMBr = NULL; ··· 5957 5925 int bytes_returned = 0; 5958 5926 char *data_offset; 5959 5927 __u16 params, param_offset, offset, byte_count, count; 5928 + int remap = cifs_remap(cifs_sb); 5960 5929 5961 5930 cifs_dbg(FYI, "In SetTimes\n"); 5962 5931 ··· 6019 5986 6020 5987 if (rc == -EAGAIN) 6021 5988 goto SetTimesRetry; 5989 + 5990 + if (rc == -EOPNOTSUPP) 5991 + return CIFSSMBSetPathInfoFB(xid, tcon, fileName, data, 5992 + nls_codepage, cifs_sb); 6022 5993 6023 5994 return rc; 6024 5995 }
+2 -2
fs/cifs/smb1ops.c
··· 688 688 dosattrs = cifsInode->cifsAttrs|ATTR_READONLY; 689 689 info.Attributes = cpu_to_le32(dosattrs); 690 690 rc = CIFSSMBSetPathInfo(xid, tcon, full_path, &info, cifs_sb->local_nls, 691 - cifs_remap(cifs_sb)); 691 + cifs_sb); 692 692 if (rc == 0) 693 693 cifsInode->cifsAttrs = dosattrs; 694 694 } ··· 783 783 tcon = tlink_tcon(tlink); 784 784 785 785 rc = CIFSSMBSetPathInfo(xid, tcon, full_path, buf, cifs_sb->local_nls, 786 - cifs_remap(cifs_sb)); 786 + cifs_sb); 787 787 if (rc == 0) { 788 788 cinode->cifsAttrs = le32_to_cpu(buf->Attributes); 789 789 goto out;