FILE
dir.c
File preview with syntax highlighting.
linux-6.19.14/fs/smb/client/dir.c
1// SPDX-License-Identifier: LGPL-2.1 2/* 3 * 4 * vfs operations that deal with dentries 5 * 6 * Copyright (C) International Business Machines Corp., 2002,2009 7 * Author(s): Steve French (sfrench@us.ibm.com) 8 * 9 */ 10#include <linux/fs.h> 11#include <linux/stat.h> 12#include <linux/slab.h> 13#include <linux/namei.h> 14#include <linux/mount.h> 15#include <linux/file.h> 16#include "cifsfs.h" 17#include "cifspdu.h" 18#include "cifsglob.h" 19#include "cifsproto.h" 20#include "cifs_debug.h" 21#include "cifs_fs_sb.h" 22#include "cifs_unicode.h" 23#include "fs_context.h" 24#include "cifs_ioctl.h" 25#include "fscache.h" 26#include "cached_dir.h" 27 28static void 29renew_parental_timestamps(struct dentry *direntry) 30{ 31 /* BB check if there is a way to get the kernel to do this or if we 32 really need this */ 33 do { 34 cifs_set_time(direntry, jiffies); 35 direntry = direntry->d_parent; 36 } while (!IS_ROOT(direntry)); 37} 38 39char * 40cifs_build_path_to_root(struct smb3_fs_context *ctx, struct cifs_sb_info *cifs_sb, 41 struct cifs_tcon *tcon, int add_treename) 42{ 43 int pplen = ctx->prepath ? strlen(ctx->prepath) + 1 : 0; 44 int dfsplen; 45 char *full_path = NULL; 46 47 /* if no prefix path, simply set path to the root of share to "" */ 48 if (pplen == 0) { 49 full_path = kzalloc(1, GFP_KERNEL); 50 return full_path; 51 } 52 53 if (add_treename) 54 dfsplen = strnlen(tcon->tree_name, MAX_TREE_SIZE + 1); 55 else 56 dfsplen = 0; 57 58 full_path = kmalloc(dfsplen + pplen + 1, GFP_KERNEL); 59 if (full_path == NULL) 60 return full_path; 61 62 if (dfsplen) 63 memcpy(full_path, tcon->tree_name, dfsplen); 64 full_path[dfsplen] = CIFS_DIR_SEP(cifs_sb); 65 memcpy(full_path + dfsplen + 1, ctx->prepath, pplen); 66 convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb)); 67 return full_path; 68} 69 70/* Note: caller must free return buffer */ 71const char * 72build_path_from_dentry(struct dentry *direntry, void *page) 73{ 74 struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb); 75 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); 76 bool prefix = tcon->Flags & SMB_SHARE_IS_IN_DFS; 77 78 return build_path_from_dentry_optional_prefix(direntry, page, 79 prefix); 80} 81 82char *__build_path_from_dentry_optional_prefix(struct dentry *direntry, void *page, 83 const char *tree, int tree_len, 84 bool prefix) 85{ 86 int dfsplen; 87 int pplen = 0; 88 struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb); 89 char dirsep = CIFS_DIR_SEP(cifs_sb); 90 char *s; 91 92 if (unlikely(!page)) 93 return ERR_PTR(-ENOMEM); 94 95 if (prefix) 96 dfsplen = strnlen(tree, tree_len + 1); 97 else 98 dfsplen = 0; 99 100 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) 101 pplen = cifs_sb->prepath ? strlen(cifs_sb->prepath) + 1 : 0; 102 103 s = dentry_path_raw(direntry, page, PATH_MAX); 104 if (IS_ERR(s)) 105 return s; 106 if (!s[1]) // for root we want "", not "/" 107 s++; 108 if (s < (char *)page + pplen + dfsplen) 109 return ERR_PTR(-ENAMETOOLONG); 110 if (pplen) { 111 cifs_dbg(FYI, "using cifs_sb prepath <%s>\n", cifs_sb->prepath); 112 s -= pplen; 113 memcpy(s + 1, cifs_sb->prepath, pplen - 1); 114 *s = '/'; 115 } 116 if (dirsep != '/') { 117 /* BB test paths to Windows with '/' in the midst of prepath */ 118 char *p; 119 120 for (p = s; *p; p++) 121 if (*p == '/') 122 *p = dirsep; 123 } 124 if (dfsplen) { 125 s -= dfsplen; 126 memcpy(s, tree, dfsplen); 127 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) { 128 int i; 129 for (i = 0; i < dfsplen; i++) { 130 if (s[i] == '\\') 131 s[i] = '/'; 132 } 133 } 134 } 135 return s; 136} 137 138char *build_path_from_dentry_optional_prefix(struct dentry *direntry, void *page, 139 bool prefix) 140{ 141 struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb); 142 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); 143 144 return __build_path_from_dentry_optional_prefix(direntry, page, tcon->tree_name, 145 MAX_TREE_SIZE, prefix); 146} 147 148/* 149 * Don't allow path components longer than the server max. 150 * Don't allow the separator character in a path component. 151 * The VFS will not allow "/", but "\" is allowed by posix. 152 */ 153static int 154check_name(struct dentry *direntry, struct cifs_tcon *tcon) 155{ 156 struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb); 157 int i; 158 159 if (unlikely(tcon->fsAttrInfo.MaxPathNameComponentLength && 160 direntry->d_name.len > 161 le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength))) 162 return -ENAMETOOLONG; 163 164 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) { 165 for (i = 0; i < direntry->d_name.len; i++) { 166 if (direntry->d_name.name[i] == '\\') { 167 cifs_dbg(FYI, "Invalid file name\n"); 168 return -EINVAL; 169 } 170 } 171 } 172 return 0; 173} 174 175 176/* Inode operations in similar order to how they appear in Linux file fs.h */ 177 178static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, 179 struct tcon_link *tlink, unsigned int oflags, umode_t mode, __u32 *oplock, 180 struct cifs_fid *fid, struct cifs_open_info_data *buf) 181{ 182 int rc = -ENOENT; 183 int create_options = CREATE_NOT_DIR; 184 int desired_access; 185 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 186 struct cifs_tcon *tcon = tlink_tcon(tlink); 187 const char *full_path; 188 void *page = alloc_dentry_path(); 189 struct inode *newinode = NULL; 190 int disposition; 191 struct TCP_Server_Info *server = tcon->ses->server; 192 struct cifs_open_parms oparms; 193 struct cached_fid *parent_cfid = NULL; 194 int rdwr_for_fscache = 0; 195 __le32 lease_flags = 0; 196 197 *oplock = 0; 198 if (tcon->ses->server->oplocks) 199 *oplock = REQ_OPLOCK; 200 201 full_path = build_path_from_dentry(direntry, page); 202 if (IS_ERR(full_path)) { 203 rc = PTR_ERR(full_path); 204 goto out; 205 } 206 207 /* If we're caching, we need to be able to fill in around partial writes. */ 208 if (cifs_fscache_enabled(inode) && (oflags & O_ACCMODE) == O_WRONLY) 209 rdwr_for_fscache = 1; 210 211#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY 212 if (tcon->unix_ext && cap_unix(tcon->ses) && !tcon->broken_posix_open && 213 (CIFS_UNIX_POSIX_PATH_OPS_CAP & 214 le64_to_cpu(tcon->fsUnixInfo.Capability))) { 215 rc = cifs_posix_open(full_path, &newinode, inode->i_sb, mode, 216 oflags, oplock, &fid->netfid, xid); 217 switch (rc) { 218 case 0: 219 if (newinode == NULL) { 220 /* query inode info */ 221 goto cifs_create_get_file_info; 222 } 223 224 if (S_ISDIR(newinode->i_mode)) { 225 CIFSSMBClose(xid, tcon, fid->netfid); 226 iput(newinode); 227 rc = -EISDIR; 228 goto out; 229 } 230 231 if (!S_ISREG(newinode->i_mode)) { 232 /* 233 * The server may allow us to open things like 234 * FIFOs, but the client isn't set up to deal 235 * with that. If it's not a regular file, just 236 * close it and proceed as if it were a normal 237 * lookup. 238 */ 239 CIFSSMBClose(xid, tcon, fid->netfid); 240 goto cifs_create_get_file_info; 241 } 242 /* success, no need to query */ 243 goto cifs_create_set_dentry; 244 245 case -ENOENT: 246 goto cifs_create_get_file_info; 247 248 case -EIO: 249 case -EINVAL: 250 /* 251 * EIO could indicate that (posix open) operation is not 252 * supported, despite what server claimed in capability 253 * negotiation. 254 * 255 * POSIX open in samba versions 3.3.1 and earlier could 256 * incorrectly fail with invalid parameter. 257 */ 258 tcon->broken_posix_open = true; 259 break; 260 261 case -EREMOTE: 262 case -EOPNOTSUPP: 263 /* 264 * EREMOTE indicates DFS junction, which is not handled 265 * in posix open. If either that or op not supported 266 * returned, follow the normal lookup. 267 */ 268 break; 269 270 default: 271 goto out; 272 } 273 /* 274 * fallthrough to retry, using older open call, this is case 275 * where server does not support this SMB level, and falsely 276 * claims capability (also get here for DFS case which should be 277 * rare for path not covered on files) 278 */ 279 } 280#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ 281 282 desired_access = 0; 283 if (OPEN_FMODE(oflags) & FMODE_READ) 284 desired_access |= GENERIC_READ; /* is this too little? */ 285 if (OPEN_FMODE(oflags) & FMODE_WRITE) 286 desired_access |= GENERIC_WRITE; 287 if (rdwr_for_fscache == 1) 288 desired_access |= GENERIC_READ; 289 290 disposition = FILE_OVERWRITE_IF; 291 if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) 292 disposition = FILE_CREATE; 293 else if ((oflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC)) 294 disposition = FILE_OVERWRITE_IF; 295 else if ((oflags & O_CREAT) == O_CREAT) 296 disposition = FILE_OPEN_IF; 297 else 298 cifs_dbg(FYI, "Create flag not set in create function\n"); 299 300 /* 301 * BB add processing to set equivalent of mode - e.g. via CreateX with 302 * ACLs 303 */ 304 305 if (!server->ops->open) { 306 rc = -ENOSYS; 307 goto out; 308 } 309 310 create_options |= cifs_open_create_options(oflags, create_options); 311 /* 312 * if we're not using unix extensions, see if we need to set 313 * ATTR_READONLY on the create call 314 */ 315 if (!tcon->unix_ext && (mode & S_IWUGO) == 0) 316 create_options |= CREATE_OPTION_READONLY; 317 318 319retry_open: 320 if (tcon->cfids && direntry->d_parent && server->dialect >= SMB30_PROT_ID) { 321 parent_cfid = NULL; 322 spin_lock(&tcon->cfids->cfid_list_lock); 323 list_for_each_entry(parent_cfid, &tcon->cfids->entries, entry) { 324 if (parent_cfid->dentry == direntry->d_parent) { 325 cifs_dbg(FYI, "found a parent cached file handle\n"); 326 if (is_valid_cached_dir(parent_cfid)) { 327 lease_flags 328 |= SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET_LE; 329 memcpy(fid->parent_lease_key, 330 parent_cfid->fid.lease_key, 331 SMB2_LEASE_KEY_SIZE); 332 parent_cfid->dirents.is_valid = false; 333 parent_cfid->dirents.is_failed = true; 334 } 335 break; 336 } 337 } 338 spin_unlock(&tcon->cfids->cfid_list_lock); 339 } 340 341 oparms = (struct cifs_open_parms) { 342 .tcon = tcon, 343 .cifs_sb = cifs_sb, 344 .desired_access = desired_access, 345 .create_options = cifs_create_options(cifs_sb, create_options), 346 .disposition = disposition, 347 .path = full_path, 348 .fid = fid, 349 .lease_flags = lease_flags, 350 .mode = mode, 351 }; 352 rc = server->ops->open(xid, &oparms, oplock, buf); 353 if (rc) { 354 cifs_dbg(FYI, "cifs_create returned 0x%x\n", rc); 355 if (rc == -EACCES && rdwr_for_fscache == 1) { 356 desired_access &= ~GENERIC_READ; 357 rdwr_for_fscache = 2; 358 goto retry_open; 359 } 360 goto out; 361 } 362 if (rdwr_for_fscache == 2) 363 cifs_invalidate_cache(inode, FSCACHE_INVAL_DIO_WRITE); 364 365#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY 366 /* 367 * If Open reported that we actually created a file then we now have to 368 * set the mode if possible. 369 */ 370 if ((tcon->unix_ext) && (*oplock & CIFS_CREATE_ACTION)) { 371 struct cifs_unix_set_info_args args = { 372 .mode = mode, 373 .ctime = NO_CHANGE_64, 374 .atime = NO_CHANGE_64, 375 .mtime = NO_CHANGE_64, 376 .device = 0, 377 }; 378 379 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { 380 args.uid = current_fsuid(); 381 if (inode->i_mode & S_ISGID) 382 args.gid = inode->i_gid; 383 else 384 args.gid = current_fsgid(); 385 } else { 386 args.uid = INVALID_UID; /* no change */ 387 args.gid = INVALID_GID; /* no change */ 388 } 389 CIFSSMBUnixSetFileInfo(xid, tcon, &args, fid->netfid, 390 current->tgid); 391 } else { 392 /* 393 * BB implement mode setting via Windows security 394 * descriptors e.g. 395 */ 396 /* CIFSSMBWinSetPerms(xid,tcon,path,mode,-1,-1,nls);*/ 397 398 /* Could set r/o dos attribute if mode & 0222 == 0 */ 399 } 400 401cifs_create_get_file_info: 402 /* server might mask mode so we have to query for it */ 403 if (tcon->unix_ext) 404 rc = cifs_get_inode_info_unix(&newinode, full_path, inode->i_sb, 405 xid); 406 else { 407#else 408 { 409#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ 410 /* TODO: Add support for calling POSIX query info here, but passing in fid */ 411 rc = cifs_get_inode_info(&newinode, full_path, buf, inode->i_sb, xid, fid); 412 if (newinode) { 413 if (server->ops->set_lease_key) 414 server->ops->set_lease_key(newinode, fid); 415 if ((*oplock & CIFS_CREATE_ACTION) && S_ISREG(newinode->i_mode)) { 416 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) 417 newinode->i_mode = mode; 418 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { 419 newinode->i_uid = current_fsuid(); 420 if (inode->i_mode & S_ISGID) 421 newinode->i_gid = inode->i_gid; 422 else 423 newinode->i_gid = current_fsgid(); 424 } 425 } 426 } 427 } 428 429#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY 430cifs_create_set_dentry: 431#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ 432 if (rc != 0) { 433 cifs_dbg(FYI, "Create worked, get_inode_info failed rc = %d\n", 434 rc); 435 goto out_err; 436 } 437 438 if (newinode) 439 if (S_ISDIR(newinode->i_mode)) { 440 rc = -EISDIR; 441 goto out_err; 442 } 443 444 d_drop(direntry); 445 d_add(direntry, newinode); 446 447out: 448 free_dentry_path(page); 449 return rc; 450 451out_err: 452 if (server->ops->close) 453 server->ops->close(xid, tcon, fid); 454 if (newinode) 455 iput(newinode); 456 goto out; 457} 458 459int 460cifs_atomic_open(struct inode *inode, struct dentry *direntry, 461 struct file *file, unsigned int oflags, umode_t mode) 462{ 463 int rc; 464 unsigned int xid; 465 struct tcon_link *tlink; 466 struct cifs_tcon *tcon; 467 struct TCP_Server_Info *server; 468 struct cifs_fid fid = {}; 469 struct cifs_pending_open open; 470 __u32 oplock; 471 struct cifsFileInfo *file_info; 472 struct cifs_open_info_data buf = {}; 473 474 if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb)))) 475 return smb_EIO(smb_eio_trace_forced_shutdown); 476 477 /* 478 * Posix open is only called (at lookup time) for file create now. For 479 * opens (rather than creates), because we do not know if it is a file 480 * or directory yet, and current Samba no longer allows us to do posix 481 * open on dirs, we could end up wasting an open call on what turns out 482 * to be a dir. For file opens, we wait to call posix open till 483 * cifs_open. It could be added to atomic_open in the future but the 484 * performance tradeoff of the extra network request when EISDIR or 485 * EACCES is returned would have to be weighed against the 50% reduction 486 * in network traffic in the other paths. 487 */ 488 if (!(oflags & O_CREAT)) { 489 /* 490 * Check for hashed negative dentry. We have already revalidated 491 * the dentry and it is fine. No need to perform another lookup. 492 */ 493 if (!d_in_lookup(direntry)) 494 return -ENOENT; 495 496 return finish_no_open(file, cifs_lookup(inode, direntry, 0)); 497 } 498 499 xid = get_xid(); 500 501 cifs_dbg(FYI, "parent inode = 0x%p name is: %pd and dentry = 0x%p\n", 502 inode, direntry, direntry); 503 504 tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb)); 505 if (IS_ERR(tlink)) { 506 rc = PTR_ERR(tlink); 507 goto out_free_xid; 508 } 509 510 tcon = tlink_tcon(tlink); 511 512 rc = check_name(direntry, tcon); 513 if (rc) 514 goto out; 515 516 server = tcon->ses->server; 517 518 if (server->ops->new_lease_key) 519 server->ops->new_lease_key(&fid); 520 521 cifs_add_pending_open(&fid, tlink, &open); 522 523 rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, 524 &oplock, &fid, &buf); 525 if (rc) { 526 cifs_del_pending_open(&open); 527 goto out; 528 } 529 530 if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) 531 file->f_mode |= FMODE_CREATED; 532 533 rc = finish_open(file, direntry, generic_file_open); 534 if (rc) { 535 if (server->ops->close) 536 server->ops->close(xid, tcon, &fid); 537 cifs_del_pending_open(&open); 538 goto out; 539 } 540 541 if (file->f_flags & O_DIRECT && 542 CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) { 543 if (CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 544 file->f_op = &cifs_file_direct_nobrl_ops; 545 else 546 file->f_op = &cifs_file_direct_ops; 547 } 548 549 file_info = cifs_new_fileinfo(&fid, file, tlink, oplock, buf.symlink_target); 550 if (file_info == NULL) { 551 if (server->ops->close) 552 server->ops->close(xid, tcon, &fid); 553 cifs_del_pending_open(&open); 554 rc = -ENOMEM; 555 goto out; 556 } 557 558 fscache_use_cookie(cifs_inode_cookie(file_inode(file)), 559 file->f_mode & FMODE_WRITE); 560 561out: 562 cifs_put_tlink(tlink); 563out_free_xid: 564 free_xid(xid); 565 cifs_free_open_info(&buf); 566 return rc; 567} 568 569int cifs_create(struct mnt_idmap *idmap, struct inode *inode, 570 struct dentry *direntry, umode_t mode, bool excl) 571{ 572 int rc; 573 unsigned int xid = get_xid(); 574 /* 575 * BB below access is probably too much for mknod to request 576 * but we have to do query and setpathinfo so requesting 577 * less could fail (unless we want to request getatr and setatr 578 * permissions (only). At least for POSIX we do not have to 579 * request so much. 580 */ 581 unsigned oflags = O_EXCL | O_CREAT | O_RDWR; 582 struct tcon_link *tlink; 583 struct cifs_tcon *tcon; 584 struct TCP_Server_Info *server; 585 struct cifs_fid fid; 586 __u32 oplock; 587 struct cifs_open_info_data buf = {}; 588 589 cifs_dbg(FYI, "cifs_create parent inode = 0x%p name is: %pd and dentry = 0x%p\n", 590 inode, direntry, direntry); 591 592 if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb)))) { 593 rc = smb_EIO(smb_eio_trace_forced_shutdown); 594 goto out_free_xid; 595 } 596 597 tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb)); 598 rc = PTR_ERR(tlink); 599 if (IS_ERR(tlink)) 600 goto out_free_xid; 601 602 tcon = tlink_tcon(tlink); 603 server = tcon->ses->server; 604 605 if (server->ops->new_lease_key) 606 server->ops->new_lease_key(&fid); 607 608 rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, &oplock, &fid, &buf); 609 if (!rc && server->ops->close) 610 server->ops->close(xid, tcon, &fid); 611 612 cifs_free_open_info(&buf); 613 cifs_put_tlink(tlink); 614out_free_xid: 615 free_xid(xid); 616 return rc; 617} 618 619int cifs_mknod(struct mnt_idmap *idmap, struct inode *inode, 620 struct dentry *direntry, umode_t mode, dev_t device_number) 621{ 622 int rc = -EPERM; 623 unsigned int xid; 624 struct cifs_sb_info *cifs_sb; 625 struct tcon_link *tlink; 626 struct cifs_tcon *tcon; 627 const char *full_path; 628 void *page; 629 630 if (!old_valid_dev(device_number)) 631 return -EINVAL; 632 633 cifs_sb = CIFS_SB(inode->i_sb); 634 if (unlikely(cifs_forced_shutdown(cifs_sb))) 635 return smb_EIO(smb_eio_trace_forced_shutdown); 636 637 tlink = cifs_sb_tlink(cifs_sb); 638 if (IS_ERR(tlink)) 639 return PTR_ERR(tlink); 640 641 page = alloc_dentry_path(); 642 tcon = tlink_tcon(tlink); 643 xid = get_xid(); 644 645 full_path = build_path_from_dentry(direntry, page); 646 if (IS_ERR(full_path)) { 647 rc = PTR_ERR(full_path); 648 goto mknod_out; 649 } 650 651 trace_smb3_mknod_enter(xid, tcon->tid, tcon->ses->Suid, full_path); 652 653 rc = tcon->ses->server->ops->make_node(xid, inode, direntry, tcon, 654 full_path, mode, 655 device_number); 656 657mknod_out: 658 if (rc) 659 trace_smb3_mknod_err(xid, tcon->tid, tcon->ses->Suid, rc); 660 else 661 trace_smb3_mknod_done(xid, tcon->tid, tcon->ses->Suid); 662 663 free_dentry_path(page); 664 free_xid(xid); 665 cifs_put_tlink(tlink); 666 return rc; 667} 668 669struct dentry * 670cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, 671 unsigned int flags) 672{ 673 unsigned int xid; 674 int rc = 0; /* to get around spurious gcc warning, set to zero here */ 675 struct cifs_sb_info *cifs_sb; 676 struct tcon_link *tlink; 677 struct cifs_tcon *pTcon; 678 struct inode *newInode = NULL; 679 const char *full_path; 680 void *page; 681 int retry_count = 0; 682 struct dentry *de; 683 684 xid = get_xid(); 685 686 cifs_dbg(FYI, "parent inode = 0x%p name is: %pd and dentry = 0x%p\n", 687 parent_dir_inode, direntry, direntry); 688 689 /* check whether path exists */ 690 691 cifs_sb = CIFS_SB(parent_dir_inode->i_sb); 692 tlink = cifs_sb_tlink(cifs_sb); 693 if (IS_ERR(tlink)) { 694 de = ERR_CAST(tlink); 695 goto free_xid; 696 } 697 pTcon = tlink_tcon(tlink); 698 699 rc = check_name(direntry, pTcon); 700 if (unlikely(rc)) { 701 de = ERR_PTR(rc); 702 goto put_tlink; 703 } 704 705 /* can not grab the rename sem here since it would 706 deadlock in the cases (beginning of sys_rename itself) 707 in which we already have the sb rename sem */ 708 page = alloc_dentry_path(); 709 full_path = build_path_from_dentry(direntry, page); 710 if (IS_ERR(full_path)) { 711 de = ERR_CAST(full_path); 712 goto free_dentry_path; 713 } 714 715 if (d_really_is_positive(direntry)) { 716 cifs_dbg(FYI, "non-NULL inode in lookup\n"); 717 } else { 718 struct cached_fid *cfid = NULL; 719 720 cifs_dbg(FYI, "NULL inode in lookup\n"); 721 722 /* 723 * We can only rely on negative dentries having the same 724 * spelling as the cached dirent if case insensitivity is 725 * forced on mount. 726 * 727 * XXX: if servers correctly announce Case Sensitivity Search 728 * on GetInfo of FileFSAttributeInformation, then we can take 729 * correct action even if case insensitive is not forced on 730 * mount. 731 */ 732 if (pTcon->nocase && !open_cached_dir_by_dentry(pTcon, direntry->d_parent, &cfid)) { 733 /* 734 * dentry is negative and parent is fully cached: 735 * we can assume file does not exist 736 */ 737 if (cfid->dirents.is_valid) { 738 close_cached_dir(cfid); 739 goto out; 740 } 741 close_cached_dir(cfid); 742 } 743 } 744 cifs_dbg(FYI, "Full path: %s inode = 0x%p\n", 745 full_path, d_inode(direntry)); 746 747again: 748 if (pTcon->posix_extensions) { 749 rc = smb311_posix_get_inode_info(&newInode, full_path, NULL, 750 parent_dir_inode->i_sb, xid); 751 } else if (pTcon->unix_ext) { 752 rc = cifs_get_inode_info_unix(&newInode, full_path, 753 parent_dir_inode->i_sb, xid); 754 } else { 755 rc = cifs_get_inode_info(&newInode, full_path, NULL, 756 parent_dir_inode->i_sb, xid, NULL); 757 } 758 759 if (rc == 0) { 760 /* since paths are not looked up by component - the parent 761 directories are presumed to be good here */ 762 renew_parental_timestamps(direntry); 763 } else if (rc == -EAGAIN && retry_count++ < 10) { 764 goto again; 765 } else if (rc == -ENOENT) { 766 cifs_set_time(direntry, jiffies); 767 newInode = NULL; 768 } else { 769 if (rc != -EACCES) { 770 cifs_dbg(FYI, "Unexpected lookup error %d\n", rc); 771 /* We special case check for Access Denied - since that 772 is a common return code */ 773 } 774 newInode = ERR_PTR(rc); 775 } 776 777out: 778 de = d_splice_alias(newInode, direntry); 779free_dentry_path: 780 free_dentry_path(page); 781put_tlink: 782 cifs_put_tlink(tlink); 783free_xid: 784 free_xid(xid); 785 return de; 786} 787 788static int 789cifs_d_revalidate(struct inode *dir, const struct qstr *name, 790 struct dentry *direntry, unsigned int flags) 791{ 792 if (flags & LOOKUP_RCU) 793 return -ECHILD; 794 795 if (d_really_is_positive(direntry)) { 796 int rc; 797 struct inode *inode = d_inode(direntry); 798 799 if ((flags & LOOKUP_REVAL) && !CIFS_CACHE_READ(CIFS_I(inode))) 800 CIFS_I(inode)->time = 0; /* force reval */ 801 802 rc = cifs_revalidate_dentry(direntry); 803 if (rc) { 804 cifs_dbg(FYI, "cifs_revalidate_dentry failed with rc=%d", rc); 805 switch (rc) { 806 case -ENOENT: 807 case -ESTALE: 808 /* 809 * Those errors mean the dentry is invalid 810 * (file was deleted or recreated) 811 */ 812 return 0; 813 default: 814 /* 815 * Otherwise some unexpected error happened 816 * report it as-is to VFS layer 817 */ 818 return rc; 819 } 820 } 821 else { 822 /* 823 * If the inode wasn't known to be a dfs entry when 824 * the dentry was instantiated, such as when created 825 * via ->readdir(), it needs to be set now since the 826 * attributes will have been updated by 827 * cifs_revalidate_dentry(). 828 */ 829 if (IS_AUTOMOUNT(inode) && 830 !(direntry->d_flags & DCACHE_NEED_AUTOMOUNT)) { 831 spin_lock(&direntry->d_lock); 832 direntry->d_flags |= DCACHE_NEED_AUTOMOUNT; 833 spin_unlock(&direntry->d_lock); 834 } 835 836 return 1; 837 } 838 } else { 839 struct cifs_sb_info *cifs_sb = CIFS_SB(dir->i_sb); 840 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); 841 struct cached_fid *cfid; 842 843 if (!open_cached_dir_by_dentry(tcon, direntry->d_parent, &cfid)) { 844 /* 845 * dentry is negative and parent is fully cached: 846 * we can assume file does not exist 847 */ 848 if (cfid->dirents.is_valid) { 849 close_cached_dir(cfid); 850 return 1; 851 } 852 close_cached_dir(cfid); 853 } 854 } 855 856 /* 857 * This may be nfsd (or something), anyway, we can't see the 858 * intent of this. So, since this can be for creation, drop it. 859 */ 860 if (!flags) 861 return 0; 862 863 /* 864 * Drop the negative dentry, in order to make sure to use the 865 * case sensitive name which is specified by user if this is 866 * for creation. 867 */ 868 if (flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET)) 869 return 0; 870 871 if (time_after(jiffies, cifs_get_time(direntry) + HZ) || !lookupCacheEnabled) 872 return 0; 873 874 return 1; 875} 876 877/* static int cifs_d_delete(struct dentry *direntry) 878{ 879 int rc = 0; 880 881 cifs_dbg(FYI, "In cifs d_delete, name = %pd\n", direntry); 882 883 return rc; 884} */ 885 886const struct dentry_operations cifs_dentry_ops = { 887 .d_revalidate = cifs_d_revalidate, 888 .d_automount = cifs_d_automount, 889/* d_delete: cifs_d_delete, */ /* not needed except for debugging */ 890}; 891 892static int cifs_ci_hash(const struct dentry *dentry, struct qstr *q) 893{ 894 struct nls_table *codepage = CIFS_SB(dentry->d_sb)->local_nls; 895 unsigned long hash; 896 wchar_t c; 897 int i, charlen; 898 899 hash = init_name_hash(dentry); 900 for (i = 0; i < q->len; i += charlen) { 901 charlen = codepage->char2uni(&q->name[i], q->len - i, &c); 902 /* error out if we can't convert the character */ 903 if (unlikely(charlen < 0)) 904 return charlen; 905 hash = partial_name_hash(cifs_toupper(c), hash); 906 } 907 q->hash = end_name_hash(hash); 908 909 return 0; 910} 911 912static int cifs_ci_compare(const struct dentry *dentry, 913 unsigned int len, const char *str, const struct qstr *name) 914{ 915 struct nls_table *codepage = CIFS_SB(dentry->d_sb)->local_nls; 916 wchar_t c1, c2; 917 int i, l1, l2; 918 919 /* 920 * We make the assumption here that uppercase characters in the local 921 * codepage are always the same length as their lowercase counterparts. 922 * 923 * If that's ever not the case, then this will fail to match it. 924 */ 925 if (name->len != len) 926 return 1; 927 928 for (i = 0; i < len; i += l1) { 929 /* Convert characters in both strings to UTF-16. */ 930 l1 = codepage->char2uni(&str[i], len - i, &c1); 931 l2 = codepage->char2uni(&name->name[i], name->len - i, &c2); 932 933 /* 934 * If we can't convert either character, just declare it to 935 * be 1 byte long and compare the original byte. 936 */ 937 if (unlikely(l1 < 0 && l2 < 0)) { 938 if (str[i] != name->name[i]) 939 return 1; 940 l1 = 1; 941 continue; 942 } 943 944 /* 945 * Here, we again ass|u|me that upper/lowercase versions of 946 * a character are the same length in the local NLS. 947 */ 948 if (l1 != l2) 949 return 1; 950 951 /* Now compare uppercase versions of these characters */ 952 if (cifs_toupper(c1) != cifs_toupper(c2)) 953 return 1; 954 } 955 956 return 0; 957} 958 959const struct dentry_operations cifs_ci_dentry_ops = { 960 .d_revalidate = cifs_d_revalidate, 961 .d_hash = cifs_ci_hash, 962 .d_compare = cifs_ci_compare, 963 .d_automount = cifs_d_automount, 964};
~/
Read-only file preview.