0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/fs.h>
0012 #include <linux/pagemap.h>
0013 #include <linux/slab.h>
0014 #include <linux/stat.h>
0015 #include "cifspdu.h"
0016 #include "cifsglob.h"
0017 #include "cifsproto.h"
0018 #include "cifs_unicode.h"
0019 #include "cifs_debug.h"
0020 #include "cifs_fs_sb.h"
0021 #include "cifsfs.h"
0022 #include "smb2proto.h"
0023 #include "fs_context.h"
0024 #include "cached_dir.h"
0025
0026
0027
0028
0029
0030
0031 #define UNICODE_NAME_MAX ((4 * NAME_MAX) + 2)
0032
0033 #ifdef CONFIG_CIFS_DEBUG2
0034 static void dump_cifs_file_struct(struct file *file, char *label)
0035 {
0036 struct cifsFileInfo *cf;
0037
0038 if (file) {
0039 cf = file->private_data;
0040 if (cf == NULL) {
0041 cifs_dbg(FYI, "empty cifs private file data\n");
0042 return;
0043 }
0044 if (cf->invalidHandle)
0045 cifs_dbg(FYI, "Invalid handle\n");
0046 if (cf->srch_inf.endOfSearch)
0047 cifs_dbg(FYI, "end of search\n");
0048 if (cf->srch_inf.emptyDir)
0049 cifs_dbg(FYI, "empty dir\n");
0050 }
0051 }
0052 #else
0053 static inline void dump_cifs_file_struct(struct file *file, char *label)
0054 {
0055 }
0056 #endif
0057
0058
0059
0060
0061
0062
0063
0064
0065 static void
0066 cifs_prime_dcache(struct dentry *parent, struct qstr *name,
0067 struct cifs_fattr *fattr)
0068 {
0069 struct dentry *dentry, *alias;
0070 struct inode *inode;
0071 struct super_block *sb = parent->d_sb;
0072 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
0073 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
0074
0075 cifs_dbg(FYI, "%s: for %s\n", __func__, name->name);
0076
0077 dentry = d_hash_and_lookup(parent, name);
0078 if (!dentry) {
0079
0080
0081
0082
0083
0084
0085 if (fattr->cf_flags & CIFS_FATTR_NEED_REVAL)
0086 return;
0087 retry:
0088 dentry = d_alloc_parallel(parent, name, &wq);
0089 }
0090 if (IS_ERR(dentry))
0091 return;
0092 if (!d_in_lookup(dentry)) {
0093 inode = d_inode(dentry);
0094 if (inode) {
0095 if (d_mountpoint(dentry)) {
0096 dput(dentry);
0097 return;
0098 }
0099
0100
0101
0102
0103
0104 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM))
0105 fattr->cf_uniqueid = CIFS_I(inode)->uniqueid;
0106
0107
0108
0109 if (CIFS_I(inode)->uniqueid == fattr->cf_uniqueid &&
0110 cifs_fattr_to_inode(inode, fattr) == 0) {
0111 dput(dentry);
0112 return;
0113 }
0114 }
0115 d_invalidate(dentry);
0116 dput(dentry);
0117 goto retry;
0118 } else {
0119 inode = cifs_iget(sb, fattr);
0120 if (!inode)
0121 inode = ERR_PTR(-ENOMEM);
0122 alias = d_splice_alias(inode, dentry);
0123 d_lookup_done(dentry);
0124 if (alias && !IS_ERR(alias))
0125 dput(alias);
0126 }
0127 dput(dentry);
0128 }
0129
0130 static bool reparse_file_needs_reval(const struct cifs_fattr *fattr)
0131 {
0132 if (!(fattr->cf_cifsattrs & ATTR_REPARSE))
0133 return false;
0134
0135
0136
0137
0138
0139
0140
0141 switch (fattr->cf_cifstag) {
0142 case IO_REPARSE_TAG_DFS:
0143 case IO_REPARSE_TAG_DFSR:
0144 case IO_REPARSE_TAG_SYMLINK:
0145 case IO_REPARSE_TAG_NFS:
0146 case 0:
0147 return true;
0148 }
0149 return false;
0150 }
0151
0152 static void
0153 cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb)
0154 {
0155 fattr->cf_uid = cifs_sb->ctx->linux_uid;
0156 fattr->cf_gid = cifs_sb->ctx->linux_gid;
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166 if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
0167 fattr->cf_mode = S_IFDIR | cifs_sb->ctx->dir_mode;
0168 fattr->cf_dtype = DT_DIR;
0169 } else if (fattr->cf_cifstag == IO_REPARSE_TAG_LX_SYMLINK) {
0170 fattr->cf_mode |= S_IFLNK | cifs_sb->ctx->file_mode;
0171 fattr->cf_dtype = DT_LNK;
0172 } else if (fattr->cf_cifstag == IO_REPARSE_TAG_LX_FIFO) {
0173 fattr->cf_mode |= S_IFIFO | cifs_sb->ctx->file_mode;
0174 fattr->cf_dtype = DT_FIFO;
0175 } else if (fattr->cf_cifstag == IO_REPARSE_TAG_AF_UNIX) {
0176 fattr->cf_mode |= S_IFSOCK | cifs_sb->ctx->file_mode;
0177 fattr->cf_dtype = DT_SOCK;
0178 } else if (fattr->cf_cifstag == IO_REPARSE_TAG_LX_CHR) {
0179 fattr->cf_mode |= S_IFCHR | cifs_sb->ctx->file_mode;
0180 fattr->cf_dtype = DT_CHR;
0181 } else if (fattr->cf_cifstag == IO_REPARSE_TAG_LX_BLK) {
0182 fattr->cf_mode |= S_IFBLK | cifs_sb->ctx->file_mode;
0183 fattr->cf_dtype = DT_BLK;
0184 } else {
0185 fattr->cf_mode = S_IFREG | cifs_sb->ctx->file_mode;
0186 fattr->cf_dtype = DT_REG;
0187 }
0188
0189
0190
0191
0192
0193
0194 if (reparse_file_needs_reval(fattr))
0195 fattr->cf_flags |= CIFS_FATTR_NEED_REVAL;
0196
0197
0198 fattr->cf_flags |= CIFS_FATTR_UNKNOWN_NLINK;
0199
0200 if (fattr->cf_cifsattrs & ATTR_READONLY)
0201 fattr->cf_mode &= ~S_IWUGO;
0202
0203
0204
0205
0206
0207
0208
0209
0210 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) ||
0211 (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID))
0212 fattr->cf_flags |= CIFS_FATTR_NEED_REVAL;
0213
0214 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL &&
0215 fattr->cf_cifsattrs & ATTR_SYSTEM) {
0216 if (fattr->cf_eof == 0) {
0217 fattr->cf_mode &= ~S_IFMT;
0218 fattr->cf_mode |= S_IFIFO;
0219 fattr->cf_dtype = DT_FIFO;
0220 } else {
0221
0222
0223
0224
0225
0226 fattr->cf_flags |= CIFS_FATTR_NEED_REVAL;
0227 }
0228 }
0229 }
0230
0231
0232 static void
0233 cifs_posix_to_fattr(struct cifs_fattr *fattr, struct smb2_posix_info *info,
0234 struct cifs_sb_info *cifs_sb)
0235 {
0236 struct smb2_posix_info_parsed parsed;
0237
0238 posix_info_parse(info, NULL, &parsed);
0239
0240 memset(fattr, 0, sizeof(*fattr));
0241 fattr->cf_uniqueid = le64_to_cpu(info->Inode);
0242 fattr->cf_bytes = le64_to_cpu(info->AllocationSize);
0243 fattr->cf_eof = le64_to_cpu(info->EndOfFile);
0244
0245 fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
0246 fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime);
0247 fattr->cf_ctime = cifs_NTtimeToUnix(info->CreationTime);
0248
0249 fattr->cf_nlink = le32_to_cpu(info->HardLinks);
0250 fattr->cf_cifsattrs = le32_to_cpu(info->DosAttributes);
0251
0252
0253
0254
0255
0256
0257 fattr->cf_mode = le32_to_cpu(info->Mode) & ~S_IFMT;
0258
0259 cifs_dbg(FYI, "posix fattr: dev %d, reparse %d, mode %o\n",
0260 le32_to_cpu(info->DeviceId),
0261 le32_to_cpu(info->ReparseTag),
0262 le32_to_cpu(info->Mode));
0263
0264 if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
0265 fattr->cf_mode |= S_IFDIR;
0266 fattr->cf_dtype = DT_DIR;
0267 } else {
0268
0269
0270
0271
0272
0273 fattr->cf_mode |= S_IFREG;
0274 fattr->cf_dtype = DT_REG;
0275 }
0276
0277 if (reparse_file_needs_reval(fattr))
0278 fattr->cf_flags |= CIFS_FATTR_NEED_REVAL;
0279
0280 sid_to_id(cifs_sb, &parsed.owner, fattr, SIDOWNER);
0281 sid_to_id(cifs_sb, &parsed.group, fattr, SIDGROUP);
0282 }
0283
0284 static void __dir_info_to_fattr(struct cifs_fattr *fattr, const void *info)
0285 {
0286 const FILE_DIRECTORY_INFO *fi = info;
0287
0288 memset(fattr, 0, sizeof(*fattr));
0289 fattr->cf_cifsattrs = le32_to_cpu(fi->ExtFileAttributes);
0290 fattr->cf_eof = le64_to_cpu(fi->EndOfFile);
0291 fattr->cf_bytes = le64_to_cpu(fi->AllocationSize);
0292 fattr->cf_createtime = le64_to_cpu(fi->CreationTime);
0293 fattr->cf_atime = cifs_NTtimeToUnix(fi->LastAccessTime);
0294 fattr->cf_ctime = cifs_NTtimeToUnix(fi->ChangeTime);
0295 fattr->cf_mtime = cifs_NTtimeToUnix(fi->LastWriteTime);
0296 }
0297
0298 void
0299 cifs_dir_info_to_fattr(struct cifs_fattr *fattr, FILE_DIRECTORY_INFO *info,
0300 struct cifs_sb_info *cifs_sb)
0301 {
0302 __dir_info_to_fattr(fattr, info);
0303 cifs_fill_common_info(fattr, cifs_sb);
0304 }
0305
0306 static void cifs_fulldir_info_to_fattr(struct cifs_fattr *fattr,
0307 SEARCH_ID_FULL_DIR_INFO *info,
0308 struct cifs_sb_info *cifs_sb)
0309 {
0310 __dir_info_to_fattr(fattr, info);
0311
0312
0313 if (fattr->cf_cifsattrs & ATTR_REPARSE)
0314 fattr->cf_cifstag = le32_to_cpu(info->EaSize);
0315 cifs_fill_common_info(fattr, cifs_sb);
0316 }
0317
0318 static void
0319 cifs_std_info_to_fattr(struct cifs_fattr *fattr, FIND_FILE_STANDARD_INFO *info,
0320 struct cifs_sb_info *cifs_sb)
0321 {
0322 int offset = cifs_sb_master_tcon(cifs_sb)->ses->server->timeAdj;
0323
0324 memset(fattr, 0, sizeof(*fattr));
0325 fattr->cf_atime = cnvrtDosUnixTm(info->LastAccessDate,
0326 info->LastAccessTime, offset);
0327 fattr->cf_ctime = cnvrtDosUnixTm(info->LastWriteDate,
0328 info->LastWriteTime, offset);
0329 fattr->cf_mtime = cnvrtDosUnixTm(info->LastWriteDate,
0330 info->LastWriteTime, offset);
0331
0332 fattr->cf_cifsattrs = le16_to_cpu(info->Attributes);
0333 fattr->cf_bytes = le32_to_cpu(info->AllocationSize);
0334 fattr->cf_eof = le32_to_cpu(info->DataSize);
0335
0336 cifs_fill_common_info(fattr, cifs_sb);
0337 }
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371 static int
0372 _initiate_cifs_search(const unsigned int xid, struct file *file,
0373 const char *full_path)
0374 {
0375 __u16 search_flags;
0376 int rc = 0;
0377 struct cifsFileInfo *cifsFile;
0378 struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file);
0379 struct tcon_link *tlink = NULL;
0380 struct cifs_tcon *tcon;
0381 struct TCP_Server_Info *server;
0382
0383 if (file->private_data == NULL) {
0384 tlink = cifs_sb_tlink(cifs_sb);
0385 if (IS_ERR(tlink))
0386 return PTR_ERR(tlink);
0387
0388 cifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
0389 if (cifsFile == NULL) {
0390 rc = -ENOMEM;
0391 goto error_exit;
0392 }
0393 spin_lock_init(&cifsFile->file_info_lock);
0394 file->private_data = cifsFile;
0395 cifsFile->tlink = cifs_get_tlink(tlink);
0396 tcon = tlink_tcon(tlink);
0397 } else {
0398 cifsFile = file->private_data;
0399 tcon = tlink_tcon(cifsFile->tlink);
0400 }
0401
0402 server = tcon->ses->server;
0403
0404 if (!server->ops->query_dir_first) {
0405 rc = -ENOSYS;
0406 goto error_exit;
0407 }
0408
0409 cifsFile->invalidHandle = true;
0410 cifsFile->srch_inf.endOfSearch = false;
0411
0412 cifs_dbg(FYI, "Full path: %s start at: %lld\n", full_path, file->f_pos);
0413
0414 ffirst_retry:
0415
0416
0417
0418 if (tcon->unix_ext)
0419 cifsFile->srch_inf.info_level = SMB_FIND_FILE_UNIX;
0420 else if (tcon->posix_extensions)
0421 cifsFile->srch_inf.info_level = SMB_FIND_FILE_POSIX_INFO;
0422 else if ((tcon->ses->capabilities &
0423 tcon->ses->server->vals->cap_nt_find) == 0) {
0424 cifsFile->srch_inf.info_level = SMB_FIND_FILE_INFO_STANDARD;
0425 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
0426 cifsFile->srch_inf.info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO;
0427 } else {
0428 cifsFile->srch_inf.info_level = SMB_FIND_FILE_DIRECTORY_INFO;
0429 }
0430
0431 search_flags = CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME;
0432 if (backup_cred(cifs_sb))
0433 search_flags |= CIFS_SEARCH_BACKUP_SEARCH;
0434
0435 rc = server->ops->query_dir_first(xid, tcon, full_path, cifs_sb,
0436 &cifsFile->fid, search_flags,
0437 &cifsFile->srch_inf);
0438
0439 if (rc == 0)
0440 cifsFile->invalidHandle = false;
0441
0442
0443
0444 else if ((rc == -EOPNOTSUPP) &&
0445 (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
0446 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM;
0447 goto ffirst_retry;
0448 }
0449 error_exit:
0450 cifs_put_tlink(tlink);
0451 return rc;
0452 }
0453
0454 static int
0455 initiate_cifs_search(const unsigned int xid, struct file *file,
0456 const char *full_path)
0457 {
0458 int rc, retry_count = 0;
0459
0460 do {
0461 rc = _initiate_cifs_search(xid, file, full_path);
0462
0463
0464
0465
0466 if (rc != -EDEADLK)
0467 break;
0468
0469 usleep_range(512, 2048);
0470 } while (retry_count++ < 5);
0471
0472 return rc;
0473 }
0474
0475
0476 static int cifs_unicode_bytelen(const char *str)
0477 {
0478 int len;
0479 const __le16 *ustr = (const __le16 *)str;
0480
0481 for (len = 0; len <= PATH_MAX; len++) {
0482 if (ustr[len] == 0)
0483 return len << 1;
0484 }
0485 cifs_dbg(FYI, "Unicode string longer than PATH_MAX found\n");
0486 return len << 1;
0487 }
0488
0489 static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level)
0490 {
0491 char *new_entry;
0492 FILE_DIRECTORY_INFO *pDirInfo = (FILE_DIRECTORY_INFO *)old_entry;
0493
0494 if (level == SMB_FIND_FILE_INFO_STANDARD) {
0495 FIND_FILE_STANDARD_INFO *pfData;
0496 pfData = (FIND_FILE_STANDARD_INFO *)pDirInfo;
0497
0498 new_entry = old_entry + sizeof(FIND_FILE_STANDARD_INFO) +
0499 pfData->FileNameLength;
0500 } else {
0501 u32 next_offset = le32_to_cpu(pDirInfo->NextEntryOffset);
0502
0503 if (old_entry + next_offset < old_entry) {
0504 cifs_dbg(VFS, "Invalid offset %u\n", next_offset);
0505 return NULL;
0506 }
0507 new_entry = old_entry + next_offset;
0508 }
0509 cifs_dbg(FYI, "new entry %p old entry %p\n", new_entry, old_entry);
0510
0511 if (new_entry >= end_of_smb) {
0512 cifs_dbg(VFS, "search entry %p began after end of SMB %p old entry %p\n",
0513 new_entry, end_of_smb, old_entry);
0514 return NULL;
0515 } else if (((level == SMB_FIND_FILE_INFO_STANDARD) &&
0516 (new_entry + sizeof(FIND_FILE_STANDARD_INFO) > end_of_smb))
0517 || ((level != SMB_FIND_FILE_INFO_STANDARD) &&
0518 (new_entry + sizeof(FILE_DIRECTORY_INFO) > end_of_smb))) {
0519 cifs_dbg(VFS, "search entry %p extends after end of SMB %p\n",
0520 new_entry, end_of_smb);
0521 return NULL;
0522 } else
0523 return new_entry;
0524
0525 }
0526
0527 struct cifs_dirent {
0528 const char *name;
0529 size_t namelen;
0530 u32 resume_key;
0531 u64 ino;
0532 };
0533
0534 static void cifs_fill_dirent_posix(struct cifs_dirent *de,
0535 const struct smb2_posix_info *info)
0536 {
0537 struct smb2_posix_info_parsed parsed;
0538
0539
0540 if (posix_info_parse(info, NULL, &parsed) < 0) {
0541 cifs_dbg(VFS, "Invalid POSIX info payload\n");
0542 return;
0543 }
0544
0545 de->name = parsed.name;
0546 de->namelen = parsed.name_len;
0547 de->resume_key = info->Ignored;
0548 de->ino = le64_to_cpu(info->Inode);
0549 }
0550
0551 static void cifs_fill_dirent_unix(struct cifs_dirent *de,
0552 const FILE_UNIX_INFO *info, bool is_unicode)
0553 {
0554 de->name = &info->FileName[0];
0555 if (is_unicode)
0556 de->namelen = cifs_unicode_bytelen(de->name);
0557 else
0558 de->namelen = strnlen(de->name, PATH_MAX);
0559 de->resume_key = info->ResumeKey;
0560 de->ino = le64_to_cpu(info->basic.UniqueId);
0561 }
0562
0563 static void cifs_fill_dirent_dir(struct cifs_dirent *de,
0564 const FILE_DIRECTORY_INFO *info)
0565 {
0566 de->name = &info->FileName[0];
0567 de->namelen = le32_to_cpu(info->FileNameLength);
0568 de->resume_key = info->FileIndex;
0569 }
0570
0571 static void cifs_fill_dirent_full(struct cifs_dirent *de,
0572 const FILE_FULL_DIRECTORY_INFO *info)
0573 {
0574 de->name = &info->FileName[0];
0575 de->namelen = le32_to_cpu(info->FileNameLength);
0576 de->resume_key = info->FileIndex;
0577 }
0578
0579 static void cifs_fill_dirent_search(struct cifs_dirent *de,
0580 const SEARCH_ID_FULL_DIR_INFO *info)
0581 {
0582 de->name = &info->FileName[0];
0583 de->namelen = le32_to_cpu(info->FileNameLength);
0584 de->resume_key = info->FileIndex;
0585 de->ino = le64_to_cpu(info->UniqueId);
0586 }
0587
0588 static void cifs_fill_dirent_both(struct cifs_dirent *de,
0589 const FILE_BOTH_DIRECTORY_INFO *info)
0590 {
0591 de->name = &info->FileName[0];
0592 de->namelen = le32_to_cpu(info->FileNameLength);
0593 de->resume_key = info->FileIndex;
0594 }
0595
0596 static void cifs_fill_dirent_std(struct cifs_dirent *de,
0597 const FIND_FILE_STANDARD_INFO *info)
0598 {
0599 de->name = &info->FileName[0];
0600
0601 de->namelen = info->FileNameLength;
0602 de->resume_key = info->ResumeKey;
0603 }
0604
0605 static int cifs_fill_dirent(struct cifs_dirent *de, const void *info,
0606 u16 level, bool is_unicode)
0607 {
0608 memset(de, 0, sizeof(*de));
0609
0610 switch (level) {
0611 case SMB_FIND_FILE_POSIX_INFO:
0612 cifs_fill_dirent_posix(de, info);
0613 break;
0614 case SMB_FIND_FILE_UNIX:
0615 cifs_fill_dirent_unix(de, info, is_unicode);
0616 break;
0617 case SMB_FIND_FILE_DIRECTORY_INFO:
0618 cifs_fill_dirent_dir(de, info);
0619 break;
0620 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
0621 cifs_fill_dirent_full(de, info);
0622 break;
0623 case SMB_FIND_FILE_ID_FULL_DIR_INFO:
0624 cifs_fill_dirent_search(de, info);
0625 break;
0626 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
0627 cifs_fill_dirent_both(de, info);
0628 break;
0629 case SMB_FIND_FILE_INFO_STANDARD:
0630 cifs_fill_dirent_std(de, info);
0631 break;
0632 default:
0633 cifs_dbg(FYI, "Unknown findfirst level %d\n", level);
0634 return -EINVAL;
0635 }
0636
0637 return 0;
0638 }
0639
0640 #define UNICODE_DOT cpu_to_le16(0x2e)
0641
0642
0643 static int cifs_entry_is_dot(struct cifs_dirent *de, bool is_unicode)
0644 {
0645 int rc = 0;
0646
0647 if (!de->name)
0648 return 0;
0649
0650 if (is_unicode) {
0651 __le16 *ufilename = (__le16 *)de->name;
0652 if (de->namelen == 2) {
0653
0654 if (ufilename[0] == UNICODE_DOT)
0655 rc = 1;
0656 } else if (de->namelen == 4) {
0657
0658 if (ufilename[0] == UNICODE_DOT &&
0659 ufilename[1] == UNICODE_DOT)
0660 rc = 2;
0661 }
0662 } else {
0663 if (de->namelen == 1) {
0664 if (de->name[0] == '.')
0665 rc = 1;
0666 } else if (de->namelen == 2) {
0667 if (de->name[0] == '.' && de->name[1] == '.')
0668 rc = 2;
0669 }
0670 }
0671
0672 return rc;
0673 }
0674
0675
0676
0677 static int is_dir_changed(struct file *file)
0678 {
0679 struct inode *inode = file_inode(file);
0680 struct cifsInodeInfo *cifsInfo = CIFS_I(inode);
0681
0682 if (cifsInfo->time == 0)
0683 return 1;
0684 else
0685 return 0;
0686
0687 }
0688
0689 static int cifs_save_resume_key(const char *current_entry,
0690 struct cifsFileInfo *file_info)
0691 {
0692 struct cifs_dirent de;
0693 int rc;
0694
0695 rc = cifs_fill_dirent(&de, current_entry, file_info->srch_inf.info_level,
0696 file_info->srch_inf.unicode);
0697 if (!rc) {
0698 file_info->srch_inf.presume_name = de.name;
0699 file_info->srch_inf.resume_name_len = de.namelen;
0700 file_info->srch_inf.resume_key = de.resume_key;
0701 }
0702 return rc;
0703 }
0704
0705
0706
0707
0708
0709
0710
0711
0712 static int
0713 find_cifs_entry(const unsigned int xid, struct cifs_tcon *tcon, loff_t pos,
0714 struct file *file, const char *full_path,
0715 char **current_entry, int *num_to_ret)
0716 {
0717 __u16 search_flags;
0718 int rc = 0;
0719 int pos_in_buf = 0;
0720 loff_t first_entry_in_buffer;
0721 loff_t index_to_find = pos;
0722 struct cifsFileInfo *cfile = file->private_data;
0723 struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file);
0724 struct TCP_Server_Info *server = tcon->ses->server;
0725
0726
0727 if (!server->ops->query_dir_first || !server->ops->query_dir_next)
0728 return -ENOSYS;
0729
0730 if ((cfile == NULL) || (current_entry == NULL) || (num_to_ret == NULL))
0731 return -ENOENT;
0732
0733 *current_entry = NULL;
0734 first_entry_in_buffer = cfile->srch_inf.index_of_last_entry -
0735 cfile->srch_inf.entries_in_buffer;
0736
0737
0738
0739
0740
0741
0742
0743
0744
0745 dump_cifs_file_struct(file, "In fce ");
0746 if (((index_to_find < cfile->srch_inf.index_of_last_entry) &&
0747 is_dir_changed(file)) || (index_to_find < first_entry_in_buffer)) {
0748
0749 cifs_dbg(FYI, "search backing up - close and restart search\n");
0750 spin_lock(&cfile->file_info_lock);
0751 if (server->ops->dir_needs_close(cfile)) {
0752 cfile->invalidHandle = true;
0753 spin_unlock(&cfile->file_info_lock);
0754 if (server->ops->close_dir)
0755 server->ops->close_dir(xid, tcon, &cfile->fid);
0756 } else
0757 spin_unlock(&cfile->file_info_lock);
0758 if (cfile->srch_inf.ntwrk_buf_start) {
0759 cifs_dbg(FYI, "freeing SMB ff cache buf on search rewind\n");
0760 if (cfile->srch_inf.smallBuf)
0761 cifs_small_buf_release(cfile->srch_inf.
0762 ntwrk_buf_start);
0763 else
0764 cifs_buf_release(cfile->srch_inf.
0765 ntwrk_buf_start);
0766 cfile->srch_inf.ntwrk_buf_start = NULL;
0767 }
0768 rc = initiate_cifs_search(xid, file, full_path);
0769 if (rc) {
0770 cifs_dbg(FYI, "error %d reinitiating a search on rewind\n",
0771 rc);
0772 return rc;
0773 }
0774
0775 if (cfile->srch_inf.last_entry)
0776 cifs_save_resume_key(cfile->srch_inf.last_entry, cfile);
0777 }
0778
0779 search_flags = CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME;
0780 if (backup_cred(cifs_sb))
0781 search_flags |= CIFS_SEARCH_BACKUP_SEARCH;
0782
0783 while ((index_to_find >= cfile->srch_inf.index_of_last_entry) &&
0784 (rc == 0) && !cfile->srch_inf.endOfSearch) {
0785 cifs_dbg(FYI, "calling findnext2\n");
0786 rc = server->ops->query_dir_next(xid, tcon, &cfile->fid,
0787 search_flags,
0788 &cfile->srch_inf);
0789
0790 if (cfile->srch_inf.last_entry)
0791 cifs_save_resume_key(cfile->srch_inf.last_entry, cfile);
0792 if (rc)
0793 return -ENOENT;
0794 }
0795 if (index_to_find < cfile->srch_inf.index_of_last_entry) {
0796
0797
0798 int i;
0799 char *cur_ent;
0800 char *end_of_smb;
0801
0802 if (cfile->srch_inf.ntwrk_buf_start == NULL) {
0803 cifs_dbg(VFS, "ntwrk_buf_start is NULL during readdir\n");
0804 return -EIO;
0805 }
0806
0807 end_of_smb = cfile->srch_inf.ntwrk_buf_start +
0808 server->ops->calc_smb_size(
0809 cfile->srch_inf.ntwrk_buf_start);
0810
0811 cur_ent = cfile->srch_inf.srch_entries_start;
0812 first_entry_in_buffer = cfile->srch_inf.index_of_last_entry
0813 - cfile->srch_inf.entries_in_buffer;
0814 pos_in_buf = index_to_find - first_entry_in_buffer;
0815 cifs_dbg(FYI, "found entry - pos_in_buf %d\n", pos_in_buf);
0816
0817 for (i = 0; (i < (pos_in_buf)) && (cur_ent != NULL); i++) {
0818
0819 cur_ent = nxt_dir_entry(cur_ent, end_of_smb,
0820 cfile->srch_inf.info_level);
0821 }
0822 if ((cur_ent == NULL) && (i < pos_in_buf)) {
0823
0824 cifs_dbg(VFS, "reached end of buf searching for pos in buf %d index to find %lld rc %d\n",
0825 pos_in_buf, index_to_find, rc);
0826 }
0827 rc = 0;
0828 *current_entry = cur_ent;
0829 } else {
0830 cifs_dbg(FYI, "index not in buffer - could not findnext into it\n");
0831 return 0;
0832 }
0833
0834 if (pos_in_buf >= cfile->srch_inf.entries_in_buffer) {
0835 cifs_dbg(FYI, "can not return entries pos_in_buf beyond last\n");
0836 *num_to_ret = 0;
0837 } else
0838 *num_to_ret = cfile->srch_inf.entries_in_buffer - pos_in_buf;
0839
0840 return rc;
0841 }
0842
0843 static bool emit_cached_dirents(struct cached_dirents *cde,
0844 struct dir_context *ctx)
0845 {
0846 struct cached_dirent *dirent;
0847 int rc;
0848
0849 list_for_each_entry(dirent, &cde->entries, entry) {
0850 if (ctx->pos >= dirent->pos)
0851 continue;
0852 ctx->pos = dirent->pos;
0853 rc = dir_emit(ctx, dirent->name, dirent->namelen,
0854 dirent->fattr.cf_uniqueid,
0855 dirent->fattr.cf_dtype);
0856 if (!rc)
0857 return rc;
0858 }
0859 return true;
0860 }
0861
0862 static void update_cached_dirents_count(struct cached_dirents *cde,
0863 struct dir_context *ctx)
0864 {
0865 if (cde->ctx != ctx)
0866 return;
0867 if (cde->is_valid || cde->is_failed)
0868 return;
0869
0870 cde->pos++;
0871 }
0872
0873 static void finished_cached_dirents_count(struct cached_dirents *cde,
0874 struct dir_context *ctx)
0875 {
0876 if (cde->ctx != ctx)
0877 return;
0878 if (cde->is_valid || cde->is_failed)
0879 return;
0880 if (ctx->pos != cde->pos)
0881 return;
0882
0883 cde->is_valid = 1;
0884 }
0885
0886 static void add_cached_dirent(struct cached_dirents *cde,
0887 struct dir_context *ctx,
0888 const char *name, int namelen,
0889 struct cifs_fattr *fattr)
0890 {
0891 struct cached_dirent *de;
0892
0893 if (cde->ctx != ctx)
0894 return;
0895 if (cde->is_valid || cde->is_failed)
0896 return;
0897 if (ctx->pos != cde->pos) {
0898 cde->is_failed = 1;
0899 return;
0900 }
0901 de = kzalloc(sizeof(*de), GFP_ATOMIC);
0902 if (de == NULL) {
0903 cde->is_failed = 1;
0904 return;
0905 }
0906 de->namelen = namelen;
0907 de->name = kstrndup(name, namelen, GFP_ATOMIC);
0908 if (de->name == NULL) {
0909 kfree(de);
0910 cde->is_failed = 1;
0911 return;
0912 }
0913 de->pos = ctx->pos;
0914
0915 memcpy(&de->fattr, fattr, sizeof(struct cifs_fattr));
0916
0917 list_add_tail(&de->entry, &cde->entries);
0918 }
0919
0920 static bool cifs_dir_emit(struct dir_context *ctx,
0921 const char *name, int namelen,
0922 struct cifs_fattr *fattr,
0923 struct cached_fid *cfid)
0924 {
0925 bool rc;
0926 ino_t ino = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid);
0927
0928 rc = dir_emit(ctx, name, namelen, ino, fattr->cf_dtype);
0929 if (!rc)
0930 return rc;
0931
0932 if (cfid) {
0933 mutex_lock(&cfid->dirents.de_mutex);
0934 add_cached_dirent(&cfid->dirents, ctx, name, namelen,
0935 fattr);
0936 mutex_unlock(&cfid->dirents.de_mutex);
0937 }
0938
0939 return rc;
0940 }
0941
0942 static int cifs_filldir(char *find_entry, struct file *file,
0943 struct dir_context *ctx,
0944 char *scratch_buf, unsigned int max_len,
0945 struct cached_fid *cfid)
0946 {
0947 struct cifsFileInfo *file_info = file->private_data;
0948 struct super_block *sb = file_inode(file)->i_sb;
0949 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
0950 struct cifs_dirent de = { NULL, };
0951 struct cifs_fattr fattr;
0952 struct qstr name;
0953 int rc = 0;
0954
0955 rc = cifs_fill_dirent(&de, find_entry, file_info->srch_inf.info_level,
0956 file_info->srch_inf.unicode);
0957 if (rc)
0958 return rc;
0959
0960 if (de.namelen > max_len) {
0961 cifs_dbg(VFS, "bad search response length %zd past smb end\n",
0962 de.namelen);
0963 return -EINVAL;
0964 }
0965
0966
0967 if (cifs_entry_is_dot(&de, file_info->srch_inf.unicode))
0968 return 0;
0969
0970 if (file_info->srch_inf.unicode) {
0971 struct nls_table *nlt = cifs_sb->local_nls;
0972 int map_type;
0973
0974 map_type = cifs_remap(cifs_sb);
0975 name.name = scratch_buf;
0976 name.len =
0977 cifs_from_utf16((char *)name.name, (__le16 *)de.name,
0978 UNICODE_NAME_MAX,
0979 min_t(size_t, de.namelen,
0980 (size_t)max_len), nlt, map_type);
0981 name.len -= nls_nullsize(nlt);
0982 } else {
0983 name.name = de.name;
0984 name.len = de.namelen;
0985 }
0986
0987 switch (file_info->srch_inf.info_level) {
0988 case SMB_FIND_FILE_POSIX_INFO:
0989 cifs_posix_to_fattr(&fattr,
0990 (struct smb2_posix_info *)find_entry,
0991 cifs_sb);
0992 break;
0993 case SMB_FIND_FILE_UNIX:
0994 cifs_unix_basic_to_fattr(&fattr,
0995 &((FILE_UNIX_INFO *)find_entry)->basic,
0996 cifs_sb);
0997 break;
0998 case SMB_FIND_FILE_INFO_STANDARD:
0999 cifs_std_info_to_fattr(&fattr,
1000 (FIND_FILE_STANDARD_INFO *)find_entry,
1001 cifs_sb);
1002 break;
1003 case SMB_FIND_FILE_ID_FULL_DIR_INFO:
1004 cifs_fulldir_info_to_fattr(&fattr,
1005 (SEARCH_ID_FULL_DIR_INFO *)find_entry,
1006 cifs_sb);
1007 break;
1008 default:
1009 cifs_dir_info_to_fattr(&fattr,
1010 (FILE_DIRECTORY_INFO *)find_entry,
1011 cifs_sb);
1012 break;
1013 }
1014
1015 if (de.ino && (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
1016 fattr.cf_uniqueid = de.ino;
1017 } else {
1018 fattr.cf_uniqueid = iunique(sb, ROOT_I);
1019 cifs_autodisable_serverino(cifs_sb);
1020 }
1021
1022 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) &&
1023 couldbe_mf_symlink(&fattr))
1024
1025
1026
1027
1028
1029 fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
1030
1031 cifs_prime_dcache(file_dentry(file), &name, &fattr);
1032
1033 return !cifs_dir_emit(ctx, name.name, name.len,
1034 &fattr, cfid);
1035 }
1036
1037
1038 int cifs_readdir(struct file *file, struct dir_context *ctx)
1039 {
1040 int rc = 0;
1041 unsigned int xid;
1042 int i;
1043 struct tcon_link *tlink = NULL;
1044 struct cifs_tcon *tcon;
1045 struct cifsFileInfo *cifsFile;
1046 char *current_entry;
1047 int num_to_fill = 0;
1048 char *tmp_buf = NULL;
1049 char *end_of_smb;
1050 unsigned int max_len;
1051 const char *full_path;
1052 void *page = alloc_dentry_path();
1053 struct cached_fid *cfid = NULL;
1054 struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file);
1055
1056 xid = get_xid();
1057
1058 full_path = build_path_from_dentry(file_dentry(file), page);
1059 if (IS_ERR(full_path)) {
1060 rc = PTR_ERR(full_path);
1061 goto rddir2_exit;
1062 }
1063
1064 if (file->private_data == NULL) {
1065 tlink = cifs_sb_tlink(cifs_sb);
1066 if (IS_ERR(tlink))
1067 goto cache_not_found;
1068 tcon = tlink_tcon(tlink);
1069 } else {
1070 cifsFile = file->private_data;
1071 tcon = tlink_tcon(cifsFile->tlink);
1072 }
1073
1074 rc = open_cached_dir(xid, tcon, full_path, cifs_sb, false, &cfid);
1075 cifs_put_tlink(tlink);
1076 if (rc)
1077 goto cache_not_found;
1078
1079 mutex_lock(&cfid->dirents.de_mutex);
1080
1081
1082
1083
1084
1085 if (ctx->pos == 0 && cfid->dirents.ctx == NULL) {
1086 cfid->dirents.ctx = ctx;
1087 cfid->dirents.pos = 2;
1088 }
1089
1090
1091
1092
1093 if (cfid->dirents.is_valid) {
1094 if (!dir_emit_dots(file, ctx)) {
1095 mutex_unlock(&cfid->dirents.de_mutex);
1096 goto rddir2_exit;
1097 }
1098 emit_cached_dirents(&cfid->dirents, ctx);
1099 mutex_unlock(&cfid->dirents.de_mutex);
1100 goto rddir2_exit;
1101 }
1102 mutex_unlock(&cfid->dirents.de_mutex);
1103
1104
1105
1106
1107
1108 close_cached_dir(cfid);
1109 cfid = NULL;
1110
1111 cache_not_found:
1112
1113
1114
1115
1116 if (file->private_data == NULL) {
1117 rc = initiate_cifs_search(xid, file, full_path);
1118 cifs_dbg(FYI, "initiate cifs search rc %d\n", rc);
1119 if (rc)
1120 goto rddir2_exit;
1121 }
1122
1123 if (!dir_emit_dots(file, ctx))
1124 goto rddir2_exit;
1125
1126
1127
1128
1129
1130 cifsFile = file->private_data;
1131 if (cifsFile->srch_inf.endOfSearch) {
1132 if (cifsFile->srch_inf.emptyDir) {
1133 cifs_dbg(FYI, "End of search, empty dir\n");
1134 rc = 0;
1135 goto rddir2_exit;
1136 }
1137 }
1138
1139
1140
1141
1142 tcon = tlink_tcon(cifsFile->tlink);
1143 rc = find_cifs_entry(xid, tcon, ctx->pos, file, full_path,
1144 ¤t_entry, &num_to_fill);
1145 open_cached_dir(xid, tcon, full_path, cifs_sb, false, &cfid);
1146 if (rc) {
1147 cifs_dbg(FYI, "fce error %d\n", rc);
1148 goto rddir2_exit;
1149 } else if (current_entry != NULL) {
1150 cifs_dbg(FYI, "entry %lld found\n", ctx->pos);
1151 } else {
1152 if (cfid) {
1153 mutex_lock(&cfid->dirents.de_mutex);
1154 finished_cached_dirents_count(&cfid->dirents, ctx);
1155 mutex_unlock(&cfid->dirents.de_mutex);
1156 }
1157 cifs_dbg(FYI, "Could not find entry\n");
1158 goto rddir2_exit;
1159 }
1160 cifs_dbg(FYI, "loop through %d times filling dir for net buf %p\n",
1161 num_to_fill, cifsFile->srch_inf.ntwrk_buf_start);
1162 max_len = tcon->ses->server->ops->calc_smb_size(
1163 cifsFile->srch_inf.ntwrk_buf_start);
1164 end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + max_len;
1165
1166 tmp_buf = kmalloc(UNICODE_NAME_MAX, GFP_KERNEL);
1167 if (tmp_buf == NULL) {
1168 rc = -ENOMEM;
1169 goto rddir2_exit;
1170 }
1171
1172 for (i = 0; i < num_to_fill; i++) {
1173 if (current_entry == NULL) {
1174
1175 cifs_dbg(VFS, "past SMB end, num to fill %d i %d\n",
1176 num_to_fill, i);
1177 break;
1178 }
1179
1180
1181
1182
1183 *tmp_buf = 0;
1184 rc = cifs_filldir(current_entry, file, ctx,
1185 tmp_buf, max_len, cfid);
1186 if (rc) {
1187 if (rc > 0)
1188 rc = 0;
1189 break;
1190 }
1191
1192 ctx->pos++;
1193 if (cfid) {
1194 mutex_lock(&cfid->dirents.de_mutex);
1195 update_cached_dirents_count(&cfid->dirents, ctx);
1196 mutex_unlock(&cfid->dirents.de_mutex);
1197 }
1198
1199 if (ctx->pos ==
1200 cifsFile->srch_inf.index_of_last_entry) {
1201 cifs_dbg(FYI, "last entry in buf at pos %lld %s\n",
1202 ctx->pos, tmp_buf);
1203 cifs_save_resume_key(current_entry, cifsFile);
1204 break;
1205 } else
1206 current_entry =
1207 nxt_dir_entry(current_entry, end_of_smb,
1208 cifsFile->srch_inf.info_level);
1209 }
1210 kfree(tmp_buf);
1211
1212 rddir2_exit:
1213 if (cfid)
1214 close_cached_dir(cfid);
1215 free_dentry_path(page);
1216 free_xid(xid);
1217 return rc;
1218 }