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

[CIFS] Endian convert UniqueId when reporting inode numbers from server files

Jeff made a good point that we should endian convert the UniqueId when we use
it to set i_ino Even though this value is opaque to the client, when comparing
the inode numbers of the same server file from two different clients (one
big endian, one little endian) or when we compare a big endian client's view
of i_ino with what the server thinks - we should get the same value

Signed-off-by: Steve French <sfrench@us.ibm.com>

+18 -13
+2 -1
fs/cifs/CHANGES
··· 15 15 fails to support it properly, as with Samba server versions prior to 3.3.2) 16 16 Fix "redzone overwritten" bug in cifs_put_tcon (CIFSTcon may allocate too 17 17 little memory for the "nativeFileSystem" field returned by the server 18 - during mount). 18 + during mount). Endian convert inode numbers if necessary (makes it easier 19 + to compare inode numbers on network files from big endian systems). 19 20 20 21 Version 1.56 21 22 ------------
+4 -4
fs/cifs/cifspdu.h
··· 2163 2163 __le32 Type; 2164 2164 __le64 DevMajor; 2165 2165 __le64 DevMinor; 2166 - __u64 UniqueId; 2166 + __le64 UniqueId; 2167 2167 __le64 Permissions; 2168 2168 __le64 Nlinks; 2169 2169 } __attribute__((packed)) FILE_UNIX_BASIC_INFO; /* level 0x200 QPathInfo */ ··· 2308 2308 } __attribute__((packed)); 2309 2309 2310 2310 struct file_internal_info { 2311 - __u64 UniqueId; /* inode number */ 2311 + __le64 UniqueId; /* inode number */ 2312 2312 } __attribute__((packed)); /* level 0x3ee */ 2313 2313 2314 2314 struct file_mode_info { ··· 2338 2338 __le32 Type; 2339 2339 __le64 DevMajor; 2340 2340 __le64 DevMinor; 2341 - __u64 UniqueId; 2341 + __le64 UniqueId; 2342 2342 __le64 Permissions; 2343 2343 __le64 Nlinks; 2344 2344 char FileName[1]; ··· 2386 2386 __le32 FileNameLength; 2387 2387 __le32 EaSize; /* EA size */ 2388 2388 __le32 Reserved; 2389 - __u64 UniqueId; /* inode num - le since Samba puts ino in low 32 bit*/ 2389 + __le64 UniqueId; /* inode num - le since Samba puts ino in low 32 bit*/ 2390 2390 char FileName[1]; 2391 2391 } __attribute__((packed)) SEARCH_ID_FULL_DIR_INFO; /* level 0x105 FF rsp data */ 2392 2392
+1 -1
fs/cifs/cifssmb.c
··· 3918 3918 } 3919 3919 pfinfo = (struct file_internal_info *) 3920 3920 (data_offset + (char *) &pSMBr->hdr.Protocol); 3921 - *inode_number = pfinfo->UniqueId; 3921 + *inode_number = le64_to_cpu(pfinfo->UniqueId); 3922 3922 } 3923 3923 } 3924 3924 GetInodeNumOut:
+4 -2
fs/cifs/dir.c
··· 187 187 if (!pinode) 188 188 goto posix_open_ret; /* caller does not need info */ 189 189 190 - if (*pinode == NULL) 191 - *pinode = cifs_new_inode(sb, &presp_data->UniqueId); 190 + if (*pinode == NULL) { 191 + __u64 unique_id = le64_to_cpu(presp_data->UniqueId); 192 + *pinode = cifs_new_inode(sb, &unique_id); 193 + } 192 194 /* else an inode was passed in. Update its info, don't create one */ 193 195 194 196 /* We do not need to close the file if new_inode fails since
+5 -3
fs/cifs/inode.c
··· 276 276 277 277 /* get new inode */ 278 278 if (*pinode == NULL) { 279 - *pinode = cifs_new_inode(sb, &find_data.UniqueId); 279 + __u64 unique_id = le64_to_cpu(find_data.UniqueId); 280 + *pinode = cifs_new_inode(sb, &unique_id); 280 281 if (*pinode == NULL) { 281 282 rc = -ENOMEM; 282 283 goto cgiiu_exit; ··· 1139 1138 cFYI(1, ("posix mkdir returned 0x%x", rc)); 1140 1139 d_drop(direntry); 1141 1140 } else { 1141 + __u64 unique_id; 1142 1142 if (pInfo->Type == cpu_to_le32(-1)) { 1143 1143 /* no return info, go query for it */ 1144 1144 kfree(pInfo); ··· 1153 1151 else 1154 1152 direntry->d_op = &cifs_dentry_ops; 1155 1153 1156 - newinode = cifs_new_inode(inode->i_sb, 1157 - &pInfo->UniqueId); 1154 + unique_id = le64_to_cpu(pInfo->UniqueId); 1155 + newinode = cifs_new_inode(inode->i_sb, &unique_id); 1158 1156 if (newinode == NULL) { 1159 1157 kfree(pInfo); 1160 1158 goto mkdir_get_info;
+2 -2
fs/cifs/readdir.c
··· 840 840 len = strnlen(filename, PATH_MAX); 841 841 } 842 842 843 - *pinum = pFindData->UniqueId; 843 + *pinum = le64_to_cpu(pFindData->UniqueId); 844 844 } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) { 845 845 FILE_DIRECTORY_INFO *pFindData = 846 846 (FILE_DIRECTORY_INFO *)current_entry; ··· 856 856 (SEARCH_ID_FULL_DIR_INFO *)current_entry; 857 857 filename = &pFindData->FileName[0]; 858 858 len = le32_to_cpu(pFindData->FileNameLength); 859 - *pinum = pFindData->UniqueId; 859 + *pinum = le64_to_cpu(pFindData->UniqueId); 860 860 } else if (level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) { 861 861 FILE_BOTH_DIRECTORY_INFO *pFindData = 862 862 (FILE_BOTH_DIRECTORY_INFO *)current_entry;