1 // SPDX-License-Identifier: LGPL-2.1 2 /* 3 * 4 * vfs operations that deal with io control 5 * 6 * Copyright (C) International Business Machines Corp., 2005,2013 7 * Author(s): Steve French (sfrench@us.ibm.com) 8 * 9 */ 10 11 #include <linux/fs.h> 12 #include <linux/file.h> 13 #include <linux/fileattr.h> 14 #include <linux/mount.h> 15 #include <linux/mm.h> 16 #include <linux/pagemap.h> 17 #include "cifsglob.h" 18 #include "cifsproto.h" 19 #include "cifs_debug.h" 20 #include "cifsfs.h" 21 #include "cifs_ioctl.h" 22 #include "smb2proto.h" 23 #include "smb2glob.h" 24 #include <linux/btrfs.h> 25 26 static long cifs_ioctl_query_info(unsigned int xid, struct file *filep, 27 unsigned long p) 28 { 29 struct inode *inode = file_inode(filep); 30 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 31 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); 32 struct dentry *dentry = filep->f_path.dentry; 33 const unsigned char *path; 34 void *page = alloc_dentry_path(); 35 __le16 *utf16_path = NULL, root_path; 36 int rc = 0; 37 38 path = build_path_from_dentry(dentry, page); 39 if (IS_ERR(path)) { 40 free_dentry_path(page); 41 return PTR_ERR(path); 42 } 43 44 cifs_dbg(FYI, "%s %s\n", __func__, path); 45 46 if (!path[0]) { 47 root_path = 0; 48 utf16_path = &root_path; 49 } else { 50 utf16_path = cifs_convert_path_to_utf16(path + 1, cifs_sb); 51 if (!utf16_path) { 52 rc = -ENOMEM; 53 goto ici_exit; 54 } 55 } 56 57 if (tcon->ses->server->ops->ioctl_query_info) 58 rc = tcon->ses->server->ops->ioctl_query_info( 59 xid, tcon, cifs_sb, utf16_path, 60 filep->private_data ? 0 : 1, p); 61 else 62 rc = -EOPNOTSUPP; 63 64 ici_exit: 65 if (utf16_path != &root_path) 66 kfree(utf16_path); 67 free_dentry_path(page); 68 return rc; 69 } 70 71 static int cifs_set_compression_by_path(unsigned int xid, struct dentry *dentry, 72 struct cifs_tcon *tcon, 73 __u16 compression_state) 74 { 75 struct inode *inode = d_inode(dentry); 76 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 77 struct TCP_Server_Info *server = tcon->ses->server; 78 struct cifs_open_parms oparms; 79 struct cifs_open_info_data data = {}; 80 struct cifsFileInfo *tmp_cfile = NULL; 81 struct cifs_fid fid = {}; 82 const char *full_path; 83 __u32 oplock = 0; 84 u64 uniqueid; 85 void *page; 86 int rc; 87 88 if (!server->ops->open || !server->ops->close || 89 !server->ops->query_file_info) 90 return -EOPNOTSUPP; 91 92 if (!(cifs_sb_flags(cifs_sb) & CIFS_MOUNT_SERVER_INUM) || 93 cifs_sb->mnt_cifs_serverino_autodisabled) 94 return -EOPNOTSUPP; 95 96 if (d_unhashed(dentry)) 97 return -ESTALE; 98 99 page = alloc_dentry_path(); 100 full_path = build_path_from_dentry(dentry, page); 101 if (IS_ERR(full_path)) { 102 free_dentry_path(page); 103 return PTR_ERR(full_path); 104 } 105 106 oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, FILE_WRITE_DATA | 107 FILE_READ_ATTRIBUTES, 108 FILE_OPEN, 0, ACL_NO_MODE); 109 oparms.fid = &fid; 110 111 rc = server->ops->open(xid, &oparms, &oplock, NULL); 112 if (rc) 113 goto out; 114 115 tmp_cfile = kzalloc_obj(*tmp_cfile); 116 if (!tmp_cfile) { 117 rc = -ENOMEM; 118 goto close; 119 } 120 121 tmp_cfile->fid = fid; 122 rc = server->ops->query_file_info(xid, tcon, tmp_cfile, &data); 123 if (rc) 124 goto close; 125 126 uniqueid = le64_to_cpu(data.fi.IndexNumber); 127 if (!uniqueid) { 128 rc = -EOPNOTSUPP; 129 goto close; 130 } 131 if (uniqueid != CIFS_I(inode)->uniqueid) { 132 rc = -ESTALE; 133 goto close; 134 } 135 136 rc = server->ops->set_compression(xid, tcon, tmp_cfile, 137 compression_state); 138 139 close: 140 server->ops->close(xid, tcon, &fid); 141 kfree(tmp_cfile); 142 cifs_free_open_info(&data); 143 out: 144 free_dentry_path(page); 145 return rc; 146 } 147 148 static int cifs_set_compression(unsigned int xid, struct dentry *dentry, 149 struct cifs_tcon *tcon, 150 struct cifsFileInfo *cfile, 151 __u16 compression_state) 152 { 153 struct cifsFileInfo *wfile; 154 struct cifs_tcon *wtcon; 155 struct inode *inode = d_inode(dentry); 156 int rc; 157 158 if (!tcon->ses->server->ops->set_compression) 159 return -EOPNOTSUPP; 160 161 if (cfile && (cfile->fid.access & FILE_WRITE_DATA)) { 162 rc = tcon->ses->server->ops->set_compression(xid, tcon, cfile, 163 compression_state); 164 if (rc != -EACCES) 165 return rc; 166 } 167 168 rc = cifs_get_writable_file(CIFS_I(inode), FIND_FSUID_ONLY, &wfile); 169 if (!rc) { 170 wtcon = tlink_tcon(wfile->tlink); 171 rc = wtcon->ses->server->ops->set_compression(xid, wtcon, wfile, 172 compression_state); 173 cifsFileInfo_put(wfile); 174 if (rc != -EACCES) 175 return rc; 176 } else if (rc != -EBADF) { 177 return rc; 178 } 179 180 return cifs_set_compression_by_path(xid, dentry, tcon, 181 compression_state); 182 } 183 184 int cifs_fileattr_set(const struct mnt_idmap *idmap, struct dentry *dentry, 185 struct file_kattr *fa) 186 { 187 struct cifs_sb_info *cifs_sb = CIFS_SB(dentry); 188 struct inode *inode = d_inode(dentry); 189 struct file_kattr current_fa = {}; 190 u32 allowed = FS_COMPR_FL; 191 struct tcon_link *tlink; 192 __u16 compression_state; 193 bool enable_compression; 194 struct cifs_tcon *tcon; 195 unsigned int xid; 196 int rc; 197 198 if (!fa->flags_valid) 199 return -EOPNOTSUPP; 200 201 /* 202 * chattr writes back all flags returned by fileattr_get(). Accept 203 * FS_CASEFOLD_FL only when it reflects the share's casefold state. 204 */ 205 if (fa->flags & FS_CASEFOLD_FL) { 206 rc = cifs_fileattr_get(dentry, ¤t_fa); 207 if (rc) 208 return rc; 209 if (current_fa.flags & FS_CASEFOLD_FL) 210 allowed |= FS_CASEFOLD_FL; 211 } 212 if (fa->flags & ~allowed) 213 return -EOPNOTSUPP; 214 215 enable_compression = fa->flags & FS_COMPR_FL; 216 compression_state = enable_compression ? COMPRESSION_FORMAT_DEFAULT : 217 COMPRESSION_FORMAT_NONE; 218 219 tlink = cifs_sb_tlink(cifs_sb); 220 if (IS_ERR(tlink)) 221 return PTR_ERR(tlink); 222 tcon = tlink_tcon(tlink); 223 224 xid = get_xid(); 225 rc = cifs_set_compression(xid, dentry, tcon, NULL, compression_state); 226 free_xid(xid); 227 cifs_put_tlink(tlink); 228 229 if (!rc) { 230 spin_lock(&inode->i_lock); 231 if (enable_compression) 232 CIFS_I(inode)->cifsAttrs |= FILE_ATTRIBUTE_COMPRESSED; 233 else 234 CIFS_I(inode)->cifsAttrs &= ~FILE_ATTRIBUTE_COMPRESSED; 235 spin_unlock(&inode->i_lock); 236 } 237 238 cifs_dbg(FYI, "set compress flag rc %d\n", rc); 239 return rc; 240 } 241 242 static long cifs_ioctl_copychunk(unsigned int xid, struct file *dst_file, 243 unsigned long srcfd) 244 { 245 int rc; 246 struct inode *src_inode; 247 248 cifs_dbg(FYI, "ioctl copychunk range\n"); 249 /* the destination must be opened for writing */ 250 if (!(dst_file->f_mode & FMODE_WRITE)) { 251 cifs_dbg(FYI, "file target not open for write\n"); 252 return -EINVAL; 253 } 254 255 /* check if target volume is readonly and take reference */ 256 rc = mnt_want_write_file(dst_file); 257 if (rc) { 258 cifs_dbg(FYI, "mnt_want_write failed with rc %d\n", rc); 259 return rc; 260 } 261 262 CLASS(fd, src_file)(srcfd); 263 if (fd_empty(src_file)) { 264 rc = -EBADF; 265 goto out_drop_write; 266 } 267 268 if (fd_file(src_file)->f_op->unlocked_ioctl != cifs_ioctl) { 269 rc = -EBADF; 270 cifs_dbg(VFS, "src file seems to be from a different filesystem type\n"); 271 goto out_drop_write; 272 } 273 274 src_inode = file_inode(fd_file(src_file)); 275 rc = -EINVAL; 276 if (S_ISDIR(src_inode->i_mode)) 277 goto out_drop_write; 278 279 rc = cifs_file_copychunk_range(xid, fd_file(src_file), 0, dst_file, 0, 280 src_inode->i_size, 0); 281 if (rc > 0) 282 rc = 0; 283 out_drop_write: 284 mnt_drop_write_file(dst_file); 285 return rc; 286 } 287 288 static long smb_mnt_get_tcon_info(struct cifs_tcon *tcon, void __user *arg) 289 { 290 int rc = 0; 291 struct smb_mnt_tcon_info tcon_inf; 292 293 tcon_inf.tid = tcon->tid; 294 tcon_inf.session_id = tcon->ses->Suid; 295 296 if (copy_to_user(arg, &tcon_inf, sizeof(struct smb_mnt_tcon_info))) 297 rc = -EFAULT; 298 299 return rc; 300 } 301 302 static long smb_mnt_get_fsinfo(unsigned int xid, struct cifs_tcon *tcon, 303 void __user *arg) 304 { 305 int rc = 0; 306 struct smb_mnt_fs_info *fsinf; 307 308 fsinf = kzalloc_obj(struct smb_mnt_fs_info); 309 if (fsinf == NULL) 310 return -ENOMEM; 311 312 fsinf->version = 1; 313 fsinf->protocol_id = tcon->ses->server->vals->protocol_id; 314 fsinf->tcon_flags = tcon->Flags; 315 fsinf->device_characteristics = 316 le32_to_cpu(tcon->fsDevInfo.DeviceCharacteristics); 317 fsinf->device_type = le32_to_cpu(tcon->fsDevInfo.DeviceType); 318 fsinf->fs_attributes = le32_to_cpu(tcon->fsAttrInfo.Attributes); 319 fsinf->max_path_component = 320 le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength); 321 fsinf->vol_serial_number = tcon->vol_serial_number; 322 fsinf->vol_create_time = le64_to_cpu(tcon->vol_create_time); 323 fsinf->share_flags = tcon->share_flags; 324 fsinf->share_caps = le32_to_cpu(tcon->capabilities); 325 fsinf->sector_flags = tcon->ss_flags; 326 fsinf->optimal_sector_size = tcon->perf_sector_size; 327 fsinf->max_bytes_chunk = tcon->max_bytes_chunk; 328 fsinf->maximal_access = tcon->maximal_access; 329 fsinf->cifs_posix_caps = le64_to_cpu(tcon->fsUnixInfo.Capability); 330 331 if (copy_to_user(arg, fsinf, sizeof(struct smb_mnt_fs_info))) 332 rc = -EFAULT; 333 334 kfree(fsinf); 335 return rc; 336 } 337 338 static int cifs_shutdown(struct super_block *sb, unsigned long arg) 339 { 340 struct cifs_sb_info *sbi = CIFS_SB(sb); 341 struct tcon_link *tlink; 342 struct cifs_tcon *tcon; 343 __u32 flags; 344 int rc; 345 346 if (!capable(CAP_SYS_ADMIN)) 347 return -EPERM; 348 349 if (get_user(flags, (__u32 __user *)arg)) 350 return -EFAULT; 351 352 tlink = cifs_sb_tlink(sbi); 353 if (IS_ERR(tlink)) 354 return PTR_ERR(tlink); 355 tcon = tlink_tcon(tlink); 356 357 trace_smb3_shutdown_enter(flags, tcon->tid); 358 if (flags > CIFS_GOING_FLAGS_NOLOGFLUSH) { 359 rc = -EINVAL; 360 goto shutdown_out_err; 361 } 362 363 if (cifs_forced_shutdown(sbi)) 364 goto shutdown_good; 365 366 cifs_dbg(VFS, "shut down requested (%d)", flags); 367 368 /* 369 * see: 370 * https://man7.org/linux/man-pages/man2/ioctl_xfs_goingdown.2.html 371 * for more information and description of original intent of the flags 372 */ 373 switch (flags) { 374 /* 375 * We could add support later for default flag which requires: 376 * "Flush all dirty data and metadata to disk" 377 * would need to call syncfs or equivalent to flush page cache for 378 * the mount and then issue fsync to server (if nostrictsync not set) 379 */ 380 case CIFS_GOING_FLAGS_DEFAULT: 381 cifs_dbg(FYI, "shutdown with default flag not supported\n"); 382 rc = -EINVAL; 383 goto shutdown_out_err; 384 /* 385 * FLAGS_LOGFLUSH is easy since it asks to write out metadata (not 386 * data) but metadata writes are not cached on the client, so can treat 387 * it similarly to NOLOGFLUSH 388 */ 389 case CIFS_GOING_FLAGS_LOGFLUSH: 390 case CIFS_GOING_FLAGS_NOLOGFLUSH: 391 atomic_or(CIFS_MOUNT_SHUTDOWN, &sbi->mnt_cifs_flags); 392 goto shutdown_good; 393 default: 394 rc = -EINVAL; 395 goto shutdown_out_err; 396 } 397 398 shutdown_good: 399 trace_smb3_shutdown_done(flags, tcon->tid); 400 cifs_put_tlink(tlink); 401 return 0; 402 shutdown_out_err: 403 trace_smb3_shutdown_err(rc, flags, tcon->tid); 404 cifs_put_tlink(tlink); 405 return rc; 406 } 407 408 static int cifs_dump_full_key(struct cifs_tcon *tcon, struct smb3_full_key_debug_info __user *in) 409 { 410 struct smb3_full_key_debug_info out; 411 struct cifs_ses *ses; 412 int rc = 0; 413 bool found = false; 414 u8 __user *end; 415 416 if (!smb3_encryption_required(tcon)) { 417 rc = -EOPNOTSUPP; 418 goto out; 419 } 420 421 /* copy user input into our output buffer */ 422 if (copy_from_user(&out, in, sizeof(out))) { 423 rc = -EINVAL; 424 goto out; 425 } 426 427 if (!out.session_id) { 428 /* if ses id is 0, use current user session */ 429 ses = tcon->ses; 430 } else { 431 /* otherwise if a session id is given, look for it in all our sessions */ 432 struct cifs_ses *ses_it = NULL; 433 struct TCP_Server_Info *server_it = NULL; 434 435 spin_lock(&cifs_tcp_ses_lock); 436 list_for_each_entry(server_it, &cifs_tcp_ses_list, tcp_ses_list) { 437 list_for_each_entry(ses_it, &server_it->smb_ses_list, smb_ses_list) { 438 spin_lock(&ses_it->ses_lock); 439 if (ses_it->ses_status != SES_EXITING && 440 ses_it->Suid == out.session_id) { 441 ses = ses_it; 442 /* 443 * since we are using the session outside the crit 444 * section, we need to make sure it won't be released 445 * so increment its refcount 446 */ 447 cifs_smb_ses_inc_refcount(ses); 448 spin_unlock(&ses_it->ses_lock); 449 found = true; 450 goto search_end; 451 } 452 spin_unlock(&ses_it->ses_lock); 453 } 454 } 455 search_end: 456 spin_unlock(&cifs_tcp_ses_lock); 457 if (!found) { 458 rc = -ENOENT; 459 goto out; 460 } 461 } 462 463 switch (ses->server->cipher_type) { 464 case SMB2_ENCRYPTION_AES128_CCM: 465 case SMB2_ENCRYPTION_AES128_GCM: 466 out.session_key_length = CIFS_SESS_KEY_SIZE; 467 out.server_in_key_length = out.server_out_key_length = SMB3_GCM128_CRYPTKEY_SIZE; 468 break; 469 case SMB2_ENCRYPTION_AES256_CCM: 470 case SMB2_ENCRYPTION_AES256_GCM: 471 out.session_key_length = ses->auth_key.len; 472 out.server_in_key_length = out.server_out_key_length = SMB3_GCM256_CRYPTKEY_SIZE; 473 break; 474 default: 475 rc = -EOPNOTSUPP; 476 goto out; 477 } 478 479 /* check if user buffer is big enough to store all the keys */ 480 if (out.in_size < sizeof(out) + out.session_key_length + out.server_in_key_length 481 + out.server_out_key_length) { 482 rc = -ENOBUFS; 483 goto out; 484 } 485 486 out.session_id = ses->Suid; 487 out.cipher_type = le16_to_cpu(ses->server->cipher_type); 488 489 /* overwrite user input with our output */ 490 if (copy_to_user(in, &out, sizeof(out))) { 491 rc = -EINVAL; 492 goto out; 493 } 494 495 /* append all the keys at the end of the user buffer */ 496 end = in->data; 497 if (copy_to_user(end, ses->auth_key.response, out.session_key_length)) { 498 rc = -EINVAL; 499 goto out; 500 } 501 end += out.session_key_length; 502 503 if (copy_to_user(end, ses->smb3encryptionkey, out.server_in_key_length)) { 504 rc = -EINVAL; 505 goto out; 506 } 507 end += out.server_in_key_length; 508 509 if (copy_to_user(end, ses->smb3decryptionkey, out.server_out_key_length)) { 510 rc = -EINVAL; 511 goto out; 512 } 513 514 out: 515 if (found) 516 cifs_put_smb_ses(ses); 517 return rc; 518 } 519 520 long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) 521 { 522 struct inode *inode = file_inode(filep); 523 struct smb3_key_debug_info pkey_inf; 524 int rc = -ENOTTY; /* strange error - but the precedent */ 525 unsigned int xid; 526 struct cifsFileInfo *pSMBFile = filep->private_data; 527 struct cifs_tcon *tcon; 528 struct tcon_link *tlink; 529 struct cifs_sb_info *cifs_sb; 530 531 xid = get_xid(); 532 533 cifs_dbg(FYI, "cifs ioctl 0x%x\n", command); 534 if (pSMBFile == NULL) 535 trace_smb3_ioctl(xid, 0, command); 536 else 537 trace_smb3_ioctl(xid, pSMBFile->fid.persistent_fid, command); 538 539 switch (command) { 540 case CIFS_IOC_COPYCHUNK_FILE: 541 rc = cifs_ioctl_copychunk(xid, filep, arg); 542 break; 543 case CIFS_QUERY_INFO: 544 rc = cifs_ioctl_query_info(xid, filep, arg); 545 break; 546 case CIFS_IOC_SET_INTEGRITY: 547 if (pSMBFile == NULL) 548 break; 549 tcon = tlink_tcon(pSMBFile->tlink); 550 if (tcon->ses->server->ops->set_integrity) 551 rc = tcon->ses->server->ops->set_integrity(xid, 552 tcon, pSMBFile); 553 else 554 rc = -EOPNOTSUPP; 555 break; 556 case CIFS_IOC_GET_MNT_INFO: 557 if (pSMBFile == NULL) 558 break; 559 tcon = tlink_tcon(pSMBFile->tlink); 560 rc = smb_mnt_get_fsinfo(xid, tcon, (void __user *)arg); 561 break; 562 case CIFS_IOC_GET_TCON_INFO: 563 cifs_sb = CIFS_SB(inode->i_sb); 564 tlink = cifs_sb_tlink(cifs_sb); 565 if (IS_ERR(tlink)) { 566 rc = PTR_ERR(tlink); 567 break; 568 } 569 tcon = tlink_tcon(tlink); 570 rc = smb_mnt_get_tcon_info(tcon, (void __user *)arg); 571 cifs_put_tlink(tlink); 572 break; 573 case CIFS_ENUMERATE_SNAPSHOTS: 574 if (pSMBFile == NULL) 575 break; 576 if (arg == 0) { 577 rc = -EINVAL; 578 goto cifs_ioc_exit; 579 } 580 tcon = tlink_tcon(pSMBFile->tlink); 581 if (tcon->ses->server->ops->enum_snapshots) 582 rc = tcon->ses->server->ops->enum_snapshots(xid, tcon, 583 pSMBFile, (void __user *)arg); 584 else 585 rc = -EOPNOTSUPP; 586 break; 587 case CIFS_DUMP_KEY: 588 /* 589 * Dump encryption keys. This is an old ioctl that only 590 * handles AES-128-{CCM,GCM}. 591 */ 592 if (!capable(CAP_SYS_ADMIN)) { 593 rc = -EACCES; 594 break; 595 } 596 597 cifs_sb = CIFS_SB(inode->i_sb); 598 tlink = cifs_sb_tlink(cifs_sb); 599 if (IS_ERR(tlink)) { 600 rc = PTR_ERR(tlink); 601 break; 602 } 603 tcon = tlink_tcon(tlink); 604 if (!smb3_encryption_required(tcon)) { 605 rc = -EOPNOTSUPP; 606 cifs_put_tlink(tlink); 607 break; 608 } 609 pkey_inf.cipher_type = 610 le16_to_cpu(tcon->ses->server->cipher_type); 611 pkey_inf.Suid = tcon->ses->Suid; 612 memcpy(pkey_inf.auth_key, tcon->ses->auth_key.response, 613 SMB2_NTLMV2_SESSKEY_SIZE); 614 memcpy(pkey_inf.smb3decryptionkey, 615 tcon->ses->smb3decryptionkey, SMB3_SIGN_KEY_SIZE); 616 memcpy(pkey_inf.smb3encryptionkey, 617 tcon->ses->smb3encryptionkey, SMB3_SIGN_KEY_SIZE); 618 if (copy_to_user((void __user *)arg, &pkey_inf, 619 sizeof(struct smb3_key_debug_info))) 620 rc = -EFAULT; 621 else 622 rc = 0; 623 cifs_put_tlink(tlink); 624 break; 625 case CIFS_DUMP_FULL_KEY: 626 /* 627 * Dump encryption keys (handles any key sizes) 628 */ 629 if (pSMBFile == NULL) 630 break; 631 if (!capable(CAP_SYS_ADMIN)) { 632 rc = -EACCES; 633 break; 634 } 635 cifs_sb = CIFS_SB(inode->i_sb); 636 tlink = cifs_sb_tlink(cifs_sb); 637 if (IS_ERR(tlink)) { 638 rc = PTR_ERR(tlink); 639 break; 640 } 641 642 tcon = tlink_tcon(tlink); 643 rc = cifs_dump_full_key(tcon, (void __user *)arg); 644 cifs_put_tlink(tlink); 645 break; 646 case CIFS_IOC_NOTIFY: 647 if (!S_ISDIR(inode->i_mode)) { 648 /* Notify can only be done on directories */ 649 rc = -EOPNOTSUPP; 650 break; 651 } 652 cifs_sb = CIFS_SB(inode->i_sb); 653 tlink = cifs_sb_tlink(cifs_sb); 654 if (IS_ERR(tlink)) { 655 rc = PTR_ERR(tlink); 656 break; 657 } 658 tcon = tlink_tcon(tlink); 659 if (tcon && tcon->ses->server->ops->notify) { 660 rc = tcon->ses->server->ops->notify(xid, 661 filep, (void __user *)arg, 662 false /* no ret data */); 663 cifs_dbg(FYI, "ioctl notify rc %d\n", rc); 664 } else 665 rc = -EOPNOTSUPP; 666 cifs_put_tlink(tlink); 667 break; 668 case CIFS_IOC_NOTIFY_INFO: 669 if (!S_ISDIR(inode->i_mode)) { 670 /* Notify can only be done on directories */ 671 rc = -EOPNOTSUPP; 672 break; 673 } 674 cifs_sb = CIFS_SB(inode->i_sb); 675 tlink = cifs_sb_tlink(cifs_sb); 676 if (IS_ERR(tlink)) { 677 rc = PTR_ERR(tlink); 678 break; 679 } 680 tcon = tlink_tcon(tlink); 681 if (tcon && tcon->ses->server->ops->notify) { 682 rc = tcon->ses->server->ops->notify(xid, 683 filep, (void __user *)arg, 684 true /* return details */); 685 cifs_dbg(FYI, "ioctl notify info rc %d\n", rc); 686 } else 687 rc = -EOPNOTSUPP; 688 cifs_put_tlink(tlink); 689 break; 690 case CIFS_IOC_SHUTDOWN: 691 rc = cifs_shutdown(inode->i_sb, arg); 692 break; 693 default: 694 cifs_dbg(FYI, "unsupported ioctl\n"); 695 trace_smb3_unsupported_ioctl(xid, 696 pSMBFile ? pSMBFile->fid.persistent_fid : 0, 697 command); 698 break; 699 } 700 cifs_ioc_exit: 701 free_xid(xid); 702 return rc; 703 } 704