| .. | .. |
|---|
| 32 | 32 | #include "cifs_debug.h" |
|---|
| 33 | 33 | #include "cifs_fs_sb.h" |
|---|
| 34 | 34 | #include "cifsfs.h" |
|---|
| 35 | +#include "smb2proto.h" |
|---|
| 35 | 36 | |
|---|
| 36 | 37 | /* |
|---|
| 37 | 38 | * To be safe - for UCS to UTF-8 with strings loaded with the rare long |
|---|
| .. | .. |
|---|
| 52 | 53 | return; |
|---|
| 53 | 54 | } |
|---|
| 54 | 55 | if (cf->invalidHandle) |
|---|
| 55 | | - cifs_dbg(FYI, "invalid handle\n"); |
|---|
| 56 | + cifs_dbg(FYI, "Invalid handle\n"); |
|---|
| 56 | 57 | if (cf->srch_inf.endOfSearch) |
|---|
| 57 | 58 | cifs_dbg(FYI, "end of search\n"); |
|---|
| 58 | 59 | if (cf->srch_inf.emptyDir) |
|---|
| .. | .. |
|---|
| 139 | 140 | dput(dentry); |
|---|
| 140 | 141 | } |
|---|
| 141 | 142 | |
|---|
| 143 | +static bool reparse_file_needs_reval(const struct cifs_fattr *fattr) |
|---|
| 144 | +{ |
|---|
| 145 | + if (!(fattr->cf_cifsattrs & ATTR_REPARSE)) |
|---|
| 146 | + return false; |
|---|
| 147 | + /* |
|---|
| 148 | + * The DFS tags should be only intepreted by server side as per |
|---|
| 149 | + * MS-FSCC 2.1.2.1, but let's include them anyway. |
|---|
| 150 | + * |
|---|
| 151 | + * Besides, if cf_cifstag is unset (0), then we still need it to be |
|---|
| 152 | + * revalidated to know exactly what reparse point it is. |
|---|
| 153 | + */ |
|---|
| 154 | + switch (fattr->cf_cifstag) { |
|---|
| 155 | + case IO_REPARSE_TAG_DFS: |
|---|
| 156 | + case IO_REPARSE_TAG_DFSR: |
|---|
| 157 | + case IO_REPARSE_TAG_SYMLINK: |
|---|
| 158 | + case IO_REPARSE_TAG_NFS: |
|---|
| 159 | + case 0: |
|---|
| 160 | + return true; |
|---|
| 161 | + } |
|---|
| 162 | + return false; |
|---|
| 163 | +} |
|---|
| 164 | + |
|---|
| 142 | 165 | static void |
|---|
| 143 | 166 | cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb) |
|---|
| 144 | 167 | { |
|---|
| 145 | 168 | fattr->cf_uid = cifs_sb->mnt_uid; |
|---|
| 146 | 169 | fattr->cf_gid = cifs_sb->mnt_gid; |
|---|
| 147 | 170 | |
|---|
| 171 | + /* |
|---|
| 172 | + * The IO_REPARSE_TAG_LX_ tags originally were used by WSL but they |
|---|
| 173 | + * are preferred by the Linux client in some cases since, unlike |
|---|
| 174 | + * the NFS reparse tag (or EAs), they don't require an extra query |
|---|
| 175 | + * to determine which type of special file they represent. |
|---|
| 176 | + * TODO: go through all documented reparse tags to see if we can |
|---|
| 177 | + * reasonably map some of them to directories vs. files vs. symlinks |
|---|
| 178 | + */ |
|---|
| 148 | 179 | if (fattr->cf_cifsattrs & ATTR_DIRECTORY) { |
|---|
| 149 | 180 | fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode; |
|---|
| 150 | 181 | fattr->cf_dtype = DT_DIR; |
|---|
| 151 | | - } else { |
|---|
| 182 | + } else if (fattr->cf_cifstag == IO_REPARSE_TAG_LX_SYMLINK) { |
|---|
| 183 | + fattr->cf_mode |= S_IFLNK | cifs_sb->mnt_file_mode; |
|---|
| 184 | + fattr->cf_dtype = DT_LNK; |
|---|
| 185 | + } else if (fattr->cf_cifstag == IO_REPARSE_TAG_LX_FIFO) { |
|---|
| 186 | + fattr->cf_mode |= S_IFIFO | cifs_sb->mnt_file_mode; |
|---|
| 187 | + fattr->cf_dtype = DT_FIFO; |
|---|
| 188 | + } else if (fattr->cf_cifstag == IO_REPARSE_TAG_AF_UNIX) { |
|---|
| 189 | + fattr->cf_mode |= S_IFSOCK | cifs_sb->mnt_file_mode; |
|---|
| 190 | + fattr->cf_dtype = DT_SOCK; |
|---|
| 191 | + } else if (fattr->cf_cifstag == IO_REPARSE_TAG_LX_CHR) { |
|---|
| 192 | + fattr->cf_mode |= S_IFCHR | cifs_sb->mnt_file_mode; |
|---|
| 193 | + fattr->cf_dtype = DT_CHR; |
|---|
| 194 | + } else if (fattr->cf_cifstag == IO_REPARSE_TAG_LX_BLK) { |
|---|
| 195 | + fattr->cf_mode |= S_IFBLK | cifs_sb->mnt_file_mode; |
|---|
| 196 | + fattr->cf_dtype = DT_BLK; |
|---|
| 197 | + } else { /* TODO: should we mark some other reparse points (like DFSR) as directories? */ |
|---|
| 152 | 198 | fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode; |
|---|
| 153 | 199 | fattr->cf_dtype = DT_REG; |
|---|
| 154 | 200 | } |
|---|
| .. | .. |
|---|
| 158 | 204 | * is a symbolic link, DFS referral or a reparse point with a direct |
|---|
| 159 | 205 | * access like junctions, deduplicated files, NFS symlinks. |
|---|
| 160 | 206 | */ |
|---|
| 161 | | - if (fattr->cf_cifsattrs & ATTR_REPARSE) |
|---|
| 207 | + if (reparse_file_needs_reval(fattr)) |
|---|
| 162 | 208 | fattr->cf_flags |= CIFS_FATTR_NEED_REVAL; |
|---|
| 163 | 209 | |
|---|
| 164 | 210 | /* non-unix readdir doesn't provide nlink */ |
|---|
| .. | .. |
|---|
| 174 | 220 | * may look wrong since the inodes may not have timed out by the time |
|---|
| 175 | 221 | * "ls" does a stat() call on them. |
|---|
| 176 | 222 | */ |
|---|
| 177 | | - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) |
|---|
| 223 | + if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) || |
|---|
| 224 | + (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)) |
|---|
| 178 | 225 | fattr->cf_flags |= CIFS_FATTR_NEED_REVAL; |
|---|
| 179 | 226 | |
|---|
| 180 | 227 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL && |
|---|
| .. | .. |
|---|
| 194 | 241 | } |
|---|
| 195 | 242 | } |
|---|
| 196 | 243 | |
|---|
| 244 | +/* Fill a cifs_fattr struct with info from SMB_FIND_FILE_POSIX_INFO. */ |
|---|
| 245 | +static void |
|---|
| 246 | +cifs_posix_to_fattr(struct cifs_fattr *fattr, struct smb2_posix_info *info, |
|---|
| 247 | + struct cifs_sb_info *cifs_sb) |
|---|
| 248 | +{ |
|---|
| 249 | + struct smb2_posix_info_parsed parsed; |
|---|
| 250 | + |
|---|
| 251 | + posix_info_parse(info, NULL, &parsed); |
|---|
| 252 | + |
|---|
| 253 | + memset(fattr, 0, sizeof(*fattr)); |
|---|
| 254 | + fattr->cf_uniqueid = le64_to_cpu(info->Inode); |
|---|
| 255 | + fattr->cf_bytes = le64_to_cpu(info->AllocationSize); |
|---|
| 256 | + fattr->cf_eof = le64_to_cpu(info->EndOfFile); |
|---|
| 257 | + |
|---|
| 258 | + fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime); |
|---|
| 259 | + fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime); |
|---|
| 260 | + fattr->cf_ctime = cifs_NTtimeToUnix(info->CreationTime); |
|---|
| 261 | + |
|---|
| 262 | + fattr->cf_nlink = le32_to_cpu(info->HardLinks); |
|---|
| 263 | + fattr->cf_cifsattrs = le32_to_cpu(info->DosAttributes); |
|---|
| 264 | + |
|---|
| 265 | + /* |
|---|
| 266 | + * Since we set the inode type below we need to mask off |
|---|
| 267 | + * to avoid strange results if bits set above. |
|---|
| 268 | + * XXX: why not make server&client use the type bits? |
|---|
| 269 | + */ |
|---|
| 270 | + fattr->cf_mode = le32_to_cpu(info->Mode) & ~S_IFMT; |
|---|
| 271 | + |
|---|
| 272 | + cifs_dbg(FYI, "posix fattr: dev %d, reparse %d, mode %o\n", |
|---|
| 273 | + le32_to_cpu(info->DeviceId), |
|---|
| 274 | + le32_to_cpu(info->ReparseTag), |
|---|
| 275 | + le32_to_cpu(info->Mode)); |
|---|
| 276 | + |
|---|
| 277 | + if (fattr->cf_cifsattrs & ATTR_DIRECTORY) { |
|---|
| 278 | + fattr->cf_mode |= S_IFDIR; |
|---|
| 279 | + fattr->cf_dtype = DT_DIR; |
|---|
| 280 | + } else { |
|---|
| 281 | + /* |
|---|
| 282 | + * mark anything that is not a dir as regular |
|---|
| 283 | + * file. special files should have the REPARSE |
|---|
| 284 | + * attribute and will be marked as needing revaluation |
|---|
| 285 | + */ |
|---|
| 286 | + fattr->cf_mode |= S_IFREG; |
|---|
| 287 | + fattr->cf_dtype = DT_REG; |
|---|
| 288 | + } |
|---|
| 289 | + |
|---|
| 290 | + if (reparse_file_needs_reval(fattr)) |
|---|
| 291 | + fattr->cf_flags |= CIFS_FATTR_NEED_REVAL; |
|---|
| 292 | + |
|---|
| 293 | + sid_to_id(cifs_sb, &parsed.owner, fattr, SIDOWNER); |
|---|
| 294 | + sid_to_id(cifs_sb, &parsed.group, fattr, SIDGROUP); |
|---|
| 295 | +} |
|---|
| 296 | + |
|---|
| 297 | +static void __dir_info_to_fattr(struct cifs_fattr *fattr, const void *info) |
|---|
| 298 | +{ |
|---|
| 299 | + const FILE_DIRECTORY_INFO *fi = info; |
|---|
| 300 | + |
|---|
| 301 | + memset(fattr, 0, sizeof(*fattr)); |
|---|
| 302 | + fattr->cf_cifsattrs = le32_to_cpu(fi->ExtFileAttributes); |
|---|
| 303 | + fattr->cf_eof = le64_to_cpu(fi->EndOfFile); |
|---|
| 304 | + fattr->cf_bytes = le64_to_cpu(fi->AllocationSize); |
|---|
| 305 | + fattr->cf_createtime = le64_to_cpu(fi->CreationTime); |
|---|
| 306 | + fattr->cf_atime = cifs_NTtimeToUnix(fi->LastAccessTime); |
|---|
| 307 | + fattr->cf_ctime = cifs_NTtimeToUnix(fi->ChangeTime); |
|---|
| 308 | + fattr->cf_mtime = cifs_NTtimeToUnix(fi->LastWriteTime); |
|---|
| 309 | +} |
|---|
| 310 | + |
|---|
| 197 | 311 | void |
|---|
| 198 | 312 | cifs_dir_info_to_fattr(struct cifs_fattr *fattr, FILE_DIRECTORY_INFO *info, |
|---|
| 199 | 313 | struct cifs_sb_info *cifs_sb) |
|---|
| 200 | 314 | { |
|---|
| 201 | | - memset(fattr, 0, sizeof(*fattr)); |
|---|
| 202 | | - fattr->cf_cifsattrs = le32_to_cpu(info->ExtFileAttributes); |
|---|
| 203 | | - fattr->cf_eof = le64_to_cpu(info->EndOfFile); |
|---|
| 204 | | - fattr->cf_bytes = le64_to_cpu(info->AllocationSize); |
|---|
| 205 | | - fattr->cf_createtime = le64_to_cpu(info->CreationTime); |
|---|
| 206 | | - fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime); |
|---|
| 207 | | - fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime); |
|---|
| 208 | | - fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime); |
|---|
| 315 | + __dir_info_to_fattr(fattr, info); |
|---|
| 316 | + cifs_fill_common_info(fattr, cifs_sb); |
|---|
| 317 | +} |
|---|
| 209 | 318 | |
|---|
| 319 | +static void cifs_fulldir_info_to_fattr(struct cifs_fattr *fattr, |
|---|
| 320 | + SEARCH_ID_FULL_DIR_INFO *info, |
|---|
| 321 | + struct cifs_sb_info *cifs_sb) |
|---|
| 322 | +{ |
|---|
| 323 | + __dir_info_to_fattr(fattr, info); |
|---|
| 324 | + |
|---|
| 325 | + /* See MS-FSCC 2.4.18 FileIdFullDirectoryInformation */ |
|---|
| 326 | + if (fattr->cf_cifsattrs & ATTR_REPARSE) |
|---|
| 327 | + fattr->cf_cifstag = le32_to_cpu(info->EaSize); |
|---|
| 210 | 328 | cifs_fill_common_info(fattr, cifs_sb); |
|---|
| 211 | 329 | } |
|---|
| 212 | 330 | |
|---|
| .. | .. |
|---|
| 264 | 382 | */ |
|---|
| 265 | 383 | |
|---|
| 266 | 384 | static int |
|---|
| 267 | | -initiate_cifs_search(const unsigned int xid, struct file *file) |
|---|
| 385 | +initiate_cifs_search(const unsigned int xid, struct file *file, |
|---|
| 386 | + char *full_path) |
|---|
| 268 | 387 | { |
|---|
| 269 | 388 | __u16 search_flags; |
|---|
| 270 | 389 | int rc = 0; |
|---|
| 271 | | - char *full_path = NULL; |
|---|
| 272 | 390 | struct cifsFileInfo *cifsFile; |
|---|
| 273 | 391 | struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file); |
|---|
| 274 | 392 | struct tcon_link *tlink = NULL; |
|---|
| .. | .. |
|---|
| 304 | 422 | cifsFile->invalidHandle = true; |
|---|
| 305 | 423 | cifsFile->srch_inf.endOfSearch = false; |
|---|
| 306 | 424 | |
|---|
| 307 | | - full_path = build_path_from_dentry(file_dentry(file)); |
|---|
| 308 | | - if (full_path == NULL) { |
|---|
| 309 | | - rc = -ENOMEM; |
|---|
| 310 | | - goto error_exit; |
|---|
| 311 | | - } |
|---|
| 312 | | - |
|---|
| 313 | 425 | cifs_dbg(FYI, "Full path: %s start at: %lld\n", full_path, file->f_pos); |
|---|
| 314 | 426 | |
|---|
| 315 | 427 | ffirst_retry: |
|---|
| .. | .. |
|---|
| 318 | 430 | /* if (cap_unix(tcon->ses) { */ |
|---|
| 319 | 431 | if (tcon->unix_ext) |
|---|
| 320 | 432 | cifsFile->srch_inf.info_level = SMB_FIND_FILE_UNIX; |
|---|
| 433 | + else if (tcon->posix_extensions) |
|---|
| 434 | + cifsFile->srch_inf.info_level = SMB_FIND_FILE_POSIX_INFO; |
|---|
| 321 | 435 | else if ((tcon->ses->capabilities & |
|---|
| 322 | 436 | tcon->ses->server->vals->cap_nt_find) == 0) { |
|---|
| 323 | 437 | cifsFile->srch_inf.info_level = SMB_FIND_FILE_INFO_STANDARD; |
|---|
| .. | .. |
|---|
| 346 | 460 | goto ffirst_retry; |
|---|
| 347 | 461 | } |
|---|
| 348 | 462 | error_exit: |
|---|
| 349 | | - kfree(full_path); |
|---|
| 350 | 463 | cifs_put_tlink(tlink); |
|---|
| 351 | 464 | return rc; |
|---|
| 352 | 465 | } |
|---|
| .. | .. |
|---|
| 380 | 493 | u32 next_offset = le32_to_cpu(pDirInfo->NextEntryOffset); |
|---|
| 381 | 494 | |
|---|
| 382 | 495 | if (old_entry + next_offset < old_entry) { |
|---|
| 383 | | - cifs_dbg(VFS, "invalid offset %u\n", next_offset); |
|---|
| 496 | + cifs_dbg(VFS, "Invalid offset %u\n", next_offset); |
|---|
| 384 | 497 | return NULL; |
|---|
| 385 | 498 | } |
|---|
| 386 | 499 | new_entry = old_entry + next_offset; |
|---|
| .. | .. |
|---|
| 409 | 522 | u32 resume_key; |
|---|
| 410 | 523 | u64 ino; |
|---|
| 411 | 524 | }; |
|---|
| 525 | + |
|---|
| 526 | +static void cifs_fill_dirent_posix(struct cifs_dirent *de, |
|---|
| 527 | + const struct smb2_posix_info *info) |
|---|
| 528 | +{ |
|---|
| 529 | + struct smb2_posix_info_parsed parsed; |
|---|
| 530 | + |
|---|
| 531 | + /* payload should have already been checked at this point */ |
|---|
| 532 | + if (posix_info_parse(info, NULL, &parsed) < 0) { |
|---|
| 533 | + cifs_dbg(VFS, "Invalid POSIX info payload\n"); |
|---|
| 534 | + return; |
|---|
| 535 | + } |
|---|
| 536 | + |
|---|
| 537 | + de->name = parsed.name; |
|---|
| 538 | + de->namelen = parsed.name_len; |
|---|
| 539 | + de->resume_key = info->Ignored; |
|---|
| 540 | + de->ino = le64_to_cpu(info->Inode); |
|---|
| 541 | +} |
|---|
| 412 | 542 | |
|---|
| 413 | 543 | static void cifs_fill_dirent_unix(struct cifs_dirent *de, |
|---|
| 414 | 544 | const FILE_UNIX_INFO *info, bool is_unicode) |
|---|
| .. | .. |
|---|
| 470 | 600 | memset(de, 0, sizeof(*de)); |
|---|
| 471 | 601 | |
|---|
| 472 | 602 | switch (level) { |
|---|
| 603 | + case SMB_FIND_FILE_POSIX_INFO: |
|---|
| 604 | + cifs_fill_dirent_posix(de, info); |
|---|
| 605 | + break; |
|---|
| 473 | 606 | case SMB_FIND_FILE_UNIX: |
|---|
| 474 | 607 | cifs_fill_dirent_unix(de, info, is_unicode); |
|---|
| 475 | 608 | break; |
|---|
| .. | .. |
|---|
| 570 | 703 | */ |
|---|
| 571 | 704 | static int |
|---|
| 572 | 705 | find_cifs_entry(const unsigned int xid, struct cifs_tcon *tcon, loff_t pos, |
|---|
| 573 | | - struct file *file, char **current_entry, int *num_to_ret) |
|---|
| 706 | + struct file *file, char *full_path, |
|---|
| 707 | + char **current_entry, int *num_to_ret) |
|---|
| 574 | 708 | { |
|---|
| 575 | 709 | __u16 search_flags; |
|---|
| 576 | 710 | int rc = 0; |
|---|
| .. | .. |
|---|
| 623 | 757 | ntwrk_buf_start); |
|---|
| 624 | 758 | cfile->srch_inf.ntwrk_buf_start = NULL; |
|---|
| 625 | 759 | } |
|---|
| 626 | | - rc = initiate_cifs_search(xid, file); |
|---|
| 760 | + rc = initiate_cifs_search(xid, file, full_path); |
|---|
| 627 | 761 | if (rc) { |
|---|
| 628 | 762 | cifs_dbg(FYI, "error %d reinitiating a search on rewind\n", |
|---|
| 629 | 763 | rc); |
|---|
| .. | .. |
|---|
| 745 | 879 | } |
|---|
| 746 | 880 | |
|---|
| 747 | 881 | switch (file_info->srch_inf.info_level) { |
|---|
| 882 | + case SMB_FIND_FILE_POSIX_INFO: |
|---|
| 883 | + cifs_posix_to_fattr(&fattr, |
|---|
| 884 | + (struct smb2_posix_info *)find_entry, |
|---|
| 885 | + cifs_sb); |
|---|
| 886 | + break; |
|---|
| 748 | 887 | case SMB_FIND_FILE_UNIX: |
|---|
| 749 | 888 | cifs_unix_basic_to_fattr(&fattr, |
|---|
| 750 | 889 | &((FILE_UNIX_INFO *)find_entry)->basic, |
|---|
| .. | .. |
|---|
| 754 | 893 | cifs_std_info_to_fattr(&fattr, |
|---|
| 755 | 894 | (FIND_FILE_STANDARD_INFO *)find_entry, |
|---|
| 756 | 895 | cifs_sb); |
|---|
| 896 | + break; |
|---|
| 897 | + case SMB_FIND_FILE_ID_FULL_DIR_INFO: |
|---|
| 898 | + cifs_fulldir_info_to_fattr(&fattr, |
|---|
| 899 | + (SEARCH_ID_FULL_DIR_INFO *)find_entry, |
|---|
| 900 | + cifs_sb); |
|---|
| 757 | 901 | break; |
|---|
| 758 | 902 | default: |
|---|
| 759 | 903 | cifs_dir_info_to_fattr(&fattr, |
|---|
| .. | .. |
|---|
| 797 | 941 | char *tmp_buf = NULL; |
|---|
| 798 | 942 | char *end_of_smb; |
|---|
| 799 | 943 | unsigned int max_len; |
|---|
| 944 | + char *full_path = NULL; |
|---|
| 800 | 945 | |
|---|
| 801 | 946 | xid = get_xid(); |
|---|
| 947 | + |
|---|
| 948 | + full_path = build_path_from_dentry(file_dentry(file)); |
|---|
| 949 | + if (full_path == NULL) { |
|---|
| 950 | + rc = -ENOMEM; |
|---|
| 951 | + goto rddir2_exit; |
|---|
| 952 | + } |
|---|
| 802 | 953 | |
|---|
| 803 | 954 | /* |
|---|
| 804 | 955 | * Ensure FindFirst doesn't fail before doing filldir() for '.' and |
|---|
| 805 | 956 | * '..'. Otherwise we won't be able to notify VFS in case of failure. |
|---|
| 806 | 957 | */ |
|---|
| 807 | 958 | if (file->private_data == NULL) { |
|---|
| 808 | | - rc = initiate_cifs_search(xid, file); |
|---|
| 959 | + rc = initiate_cifs_search(xid, file, full_path); |
|---|
| 809 | 960 | cifs_dbg(FYI, "initiate cifs search rc %d\n", rc); |
|---|
| 810 | 961 | if (rc) |
|---|
| 811 | 962 | goto rddir2_exit; |
|---|
| .. | .. |
|---|
| 832 | 983 | } */ |
|---|
| 833 | 984 | |
|---|
| 834 | 985 | tcon = tlink_tcon(cifsFile->tlink); |
|---|
| 835 | | - rc = find_cifs_entry(xid, tcon, ctx->pos, file, ¤t_entry, |
|---|
| 836 | | - &num_to_fill); |
|---|
| 986 | + rc = find_cifs_entry(xid, tcon, ctx->pos, file, full_path, |
|---|
| 987 | + ¤t_entry, &num_to_fill); |
|---|
| 837 | 988 | if (rc) { |
|---|
| 838 | 989 | cifs_dbg(FYI, "fce error %d\n", rc); |
|---|
| 839 | 990 | goto rddir2_exit; |
|---|
| 840 | 991 | } else if (current_entry != NULL) { |
|---|
| 841 | 992 | cifs_dbg(FYI, "entry %lld found\n", ctx->pos); |
|---|
| 842 | 993 | } else { |
|---|
| 843 | | - cifs_dbg(FYI, "could not find entry\n"); |
|---|
| 994 | + cifs_dbg(FYI, "Could not find entry\n"); |
|---|
| 844 | 995 | goto rddir2_exit; |
|---|
| 845 | 996 | } |
|---|
| 846 | 997 | cifs_dbg(FYI, "loop through %d times filling dir for net buf %p\n", |
|---|
| .. | .. |
|---|
| 891 | 1042 | kfree(tmp_buf); |
|---|
| 892 | 1043 | |
|---|
| 893 | 1044 | rddir2_exit: |
|---|
| 1045 | + kfree(full_path); |
|---|
| 894 | 1046 | free_xid(xid); |
|---|
| 895 | 1047 | return rc; |
|---|
| 896 | 1048 | } |
|---|