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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag '6.11-rc1-smb-client-fixes' of git://git.samba.org/sfrench/cifs-2.6

Pull smb client fixes from Steve French:

- two reparse point fixes

- minor cleanup

- additional trace point (to help debug a recent problem)

* tag '6.11-rc1-smb-client-fixes' of git://git.samba.org/sfrench/cifs-2.6:
cifs: update internal version number
smb: client: fix FSCTL_GET_REPARSE_POINT against NetApp
smb3: add dynamic tracepoints for shutdown ioctl
cifs: Remove cifs_aio_ctx
smb: client: handle lack of FSCTL_GET_REPARSE_POINT support

+119 -96
+2 -2
fs/smb/client/cifsfs.h
··· 147 147 #endif /* CONFIG_CIFS_NFSD_EXPORT */ 148 148 149 149 /* when changing internal version - update following two lines at same time */ 150 - #define SMB3_PRODUCT_BUILD 49 151 - #define CIFS_VERSION "2.49" 150 + #define SMB3_PRODUCT_BUILD 50 151 + #define CIFS_VERSION "2.50" 152 152 #endif /* _CIFSFS_H */
-24
fs/smb/client/cifsglob.h
··· 1471 1471 struct TCP_Server_Info *server; 1472 1472 }; 1473 1473 1474 - struct cifs_aio_ctx { 1475 - struct kref refcount; 1476 - struct list_head list; 1477 - struct mutex aio_mutex; 1478 - struct completion done; 1479 - struct iov_iter iter; 1480 - struct kiocb *iocb; 1481 - struct cifsFileInfo *cfile; 1482 - struct bio_vec *bv; 1483 - loff_t pos; 1484 - unsigned int nr_pinned_pages; 1485 - ssize_t rc; 1486 - unsigned int len; 1487 - unsigned int total_len; 1488 - unsigned int bv_need_unpin; /* If ->bv[] needs unpinning */ 1489 - bool should_dirty; 1490 - /* 1491 - * Indicates if this aio_ctx is for direct_io, 1492 - * If yes, iter is a copy of the user passed iov_iter 1493 - */ 1494 - bool direct_io; 1495 - }; 1496 - 1497 1474 struct cifs_io_request { 1498 1475 struct netfs_io_request rreq; 1499 1476 struct cifsFileInfo *cfile; ··· 1987 2010 * cifsFileInfo->file_info_lock cifsFileInfo->count cifs_new_fileinfo 1988 2011 * ->invalidHandle initiate_cifs_search 1989 2012 * ->oplock_break_cancelled 1990 - * cifs_aio_ctx->aio_mutex cifs_aio_ctx cifs_aio_ctx_alloc 1991 2013 ****************************************************************************/ 1992 2014 1993 2015 #ifdef DECLARE_GLOBALS_HERE
-2
fs/smb/client/cifsproto.h
··· 619 619 struct shash_desc *shash); 620 620 enum securityEnum cifs_select_sectype(struct TCP_Server_Info *, 621 621 enum securityEnum); 622 - struct cifs_aio_ctx *cifs_aio_ctx_alloc(void); 623 - void cifs_aio_ctx_release(struct kref *refcount); 624 622 625 623 int cifs_alloc_hash(const char *name, struct shash_desc **sdesc); 626 624 void cifs_free_hash(struct shash_desc **sdesc);
+15 -2
fs/smb/client/inode.c
··· 1042 1042 } 1043 1043 1044 1044 rc = -EOPNOTSUPP; 1045 - switch ((data->reparse.tag = tag)) { 1046 - case 0: /* SMB1 symlink */ 1045 + data->reparse.tag = tag; 1046 + if (!data->reparse.tag) { 1047 1047 if (server->ops->query_symlink) { 1048 1048 rc = server->ops->query_symlink(xid, tcon, 1049 1049 cifs_sb, full_path, 1050 1050 &data->symlink_target); 1051 + } 1052 + if (rc == -EOPNOTSUPP) 1053 + data->reparse.tag = IO_REPARSE_TAG_INTERNAL; 1054 + } 1055 + 1056 + switch (data->reparse.tag) { 1057 + case 0: /* SMB1 symlink */ 1058 + break; 1059 + case IO_REPARSE_TAG_INTERNAL: 1060 + rc = 0; 1061 + if (le32_to_cpu(data->fi.Attributes) & ATTR_DIRECTORY) { 1062 + cifs_create_junction_fattr(fattr, sb); 1063 + goto out; 1051 1064 } 1052 1065 break; 1053 1066 case IO_REPARSE_TAG_MOUNT_POINT:
+25 -7
fs/smb/client/ioctl.c
··· 170 170 static int cifs_shutdown(struct super_block *sb, unsigned long arg) 171 171 { 172 172 struct cifs_sb_info *sbi = CIFS_SB(sb); 173 + struct tcon_link *tlink; 174 + struct cifs_tcon *tcon; 173 175 __u32 flags; 176 + int rc; 174 177 175 178 if (!capable(CAP_SYS_ADMIN)) 176 179 return -EPERM; ··· 181 178 if (get_user(flags, (__u32 __user *)arg)) 182 179 return -EFAULT; 183 180 184 - if (flags > CIFS_GOING_FLAGS_NOLOGFLUSH) 185 - return -EINVAL; 181 + tlink = cifs_sb_tlink(sbi); 182 + if (IS_ERR(tlink)) 183 + return PTR_ERR(tlink); 184 + tcon = tlink_tcon(tlink); 185 + 186 + trace_smb3_shutdown_enter(flags, tcon->tid); 187 + if (flags > CIFS_GOING_FLAGS_NOLOGFLUSH) { 188 + rc = -EINVAL; 189 + goto shutdown_out_err; 190 + } 186 191 187 192 if (cifs_forced_shutdown(sbi)) 188 - return 0; 193 + goto shutdown_good; 189 194 190 195 cifs_dbg(VFS, "shut down requested (%d)", flags); 191 - /* trace_cifs_shutdown(sb, flags);*/ 192 196 193 197 /* 194 198 * see: ··· 211 201 */ 212 202 case CIFS_GOING_FLAGS_DEFAULT: 213 203 cifs_dbg(FYI, "shutdown with default flag not supported\n"); 214 - return -EINVAL; 204 + rc = -EINVAL; 205 + goto shutdown_out_err; 215 206 /* 216 207 * FLAGS_LOGFLUSH is easy since it asks to write out metadata (not 217 208 * data) but metadata writes are not cached on the client, so can treat ··· 221 210 case CIFS_GOING_FLAGS_LOGFLUSH: 222 211 case CIFS_GOING_FLAGS_NOLOGFLUSH: 223 212 sbi->mnt_cifs_flags |= CIFS_MOUNT_SHUTDOWN; 224 - return 0; 213 + goto shutdown_good; 225 214 default: 226 - return -EINVAL; 215 + rc = -EINVAL; 216 + goto shutdown_out_err; 227 217 } 218 + 219 + shutdown_good: 220 + trace_smb3_shutdown_done(flags, tcon->tid); 228 221 return 0; 222 + shutdown_out_err: 223 + trace_smb3_shutdown_err(rc, flags, tcon->tid); 224 + return rc; 229 225 } 230 226 231 227 static int cifs_dump_full_key(struct cifs_tcon *tcon, struct smb3_full_key_debug_info __user *in)
-54
fs/smb/client/misc.c
··· 995 995 return rc; 996 996 } 997 997 998 - struct cifs_aio_ctx * 999 - cifs_aio_ctx_alloc(void) 1000 - { 1001 - struct cifs_aio_ctx *ctx; 1002 - 1003 - /* 1004 - * Must use kzalloc to initialize ctx->bv to NULL and ctx->direct_io 1005 - * to false so that we know when we have to unreference pages within 1006 - * cifs_aio_ctx_release() 1007 - */ 1008 - ctx = kzalloc(sizeof(struct cifs_aio_ctx), GFP_KERNEL); 1009 - if (!ctx) 1010 - return NULL; 1011 - 1012 - INIT_LIST_HEAD(&ctx->list); 1013 - mutex_init(&ctx->aio_mutex); 1014 - init_completion(&ctx->done); 1015 - kref_init(&ctx->refcount); 1016 - return ctx; 1017 - } 1018 - 1019 - void 1020 - cifs_aio_ctx_release(struct kref *refcount) 1021 - { 1022 - struct cifs_aio_ctx *ctx = container_of(refcount, 1023 - struct cifs_aio_ctx, refcount); 1024 - 1025 - cifsFileInfo_put(ctx->cfile); 1026 - 1027 - /* 1028 - * ctx->bv is only set if setup_aio_ctx_iter() was call successfuly 1029 - * which means that iov_iter_extract_pages() was a success and thus 1030 - * that we may have references or pins on pages that we need to 1031 - * release. 1032 - */ 1033 - if (ctx->bv) { 1034 - if (ctx->should_dirty || ctx->bv_need_unpin) { 1035 - unsigned int i; 1036 - 1037 - for (i = 0; i < ctx->nr_pinned_pages; i++) { 1038 - struct page *page = ctx->bv[i].bv_page; 1039 - 1040 - if (ctx->should_dirty) 1041 - set_page_dirty(page); 1042 - if (ctx->bv_need_unpin) 1043 - unpin_user_page(page); 1044 - } 1045 - } 1046 - kvfree(ctx->bv); 1047 - } 1048 - 1049 - kfree(ctx); 1050 - } 1051 - 1052 998 /** 1053 999 * cifs_alloc_hash - allocate hash and hash context together 1054 1000 * @name: The name of the crypto hash algo
+4
fs/smb/client/reparse.c
··· 505 505 } 506 506 507 507 switch (tag) { 508 + case IO_REPARSE_TAG_INTERNAL: 509 + if (!(fattr->cf_cifsattrs & ATTR_DIRECTORY)) 510 + return false; 511 + fallthrough; 508 512 case IO_REPARSE_TAG_DFS: 509 513 case IO_REPARSE_TAG_DFSR: 510 514 case IO_REPARSE_TAG_MOUNT_POINT:
+17 -2
fs/smb/client/reparse.h
··· 12 12 #include "fs_context.h" 13 13 #include "cifsglob.h" 14 14 15 + /* 16 + * Used only by cifs.ko to ignore reparse points from files when client or 17 + * server doesn't support FSCTL_GET_REPARSE_POINT. 18 + */ 19 + #define IO_REPARSE_TAG_INTERNAL ((__u32)~0U) 20 + 15 21 static inline dev_t reparse_nfs_mkdev(struct reparse_posix_data *buf) 16 22 { 17 23 u64 v = le64_to_cpu(*(__le64 *)buf->DataBuffer); ··· 84 78 static inline bool reparse_inode_match(struct inode *inode, 85 79 struct cifs_fattr *fattr) 86 80 { 81 + struct cifsInodeInfo *cinode = CIFS_I(inode); 87 82 struct timespec64 ctime = inode_get_ctime(inode); 88 83 89 - return (CIFS_I(inode)->cifsAttrs & ATTR_REPARSE) && 90 - CIFS_I(inode)->reparse_tag == fattr->cf_cifstag && 84 + /* 85 + * Do not match reparse tags when client or server doesn't support 86 + * FSCTL_GET_REPARSE_POINT. @fattr->cf_cifstag should contain correct 87 + * reparse tag from query dir response but the client won't be able to 88 + * read the reparse point data anyway. This spares us a revalidation. 89 + */ 90 + if (cinode->reparse_tag != IO_REPARSE_TAG_INTERNAL && 91 + cinode->reparse_tag != fattr->cf_cifstag) 92 + return false; 93 + return (cinode->cifsAttrs & ATTR_REPARSE) && 91 94 timespec64_equal(&ctime, &fattr->cf_ctime); 92 95 } 93 96
+6 -2
fs/smb/client/smb2inode.c
··· 930 930 931 931 switch (rc) { 932 932 case 0: 933 + rc = parse_create_response(data, cifs_sb, &out_iov[0]); 934 + break; 933 935 case -EOPNOTSUPP: 934 936 /* 935 937 * BB TODO: When support for special files added to Samba ··· 950 948 cmds[num_cmds++] = SMB2_OP_GET_REPARSE; 951 949 952 950 oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, 953 - FILE_READ_ATTRIBUTES | FILE_READ_EA, 951 + FILE_READ_ATTRIBUTES | 952 + FILE_READ_EA | SYNCHRONIZE, 954 953 FILE_OPEN, create_options | 955 954 OPEN_REPARSE_POINT, ACL_NO_MODE); 956 955 cifs_get_readable_path(tcon, full_path, &cfile); ··· 1259 1256 cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path); 1260 1257 1261 1258 cifs_get_readable_path(tcon, full_path, &cfile); 1262 - oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, FILE_READ_ATTRIBUTES, 1259 + oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, 1260 + FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE, 1263 1261 FILE_OPEN, OPEN_REPARSE_POINT, ACL_NO_MODE); 1264 1262 rc = smb2_compound_op(xid, tcon, cifs_sb, 1265 1263 full_path, &oparms, &in_iov,
+50 -1
fs/smb/client/trace.h
··· 1388 1388 __entry->command = command; 1389 1389 ), 1390 1390 TP_printk("xid=%u fid=0x%llx ioctl cmd=0x%x", 1391 - __entry->xid, __entry->fid, __entry->command) 1391 + __entry->xid, __entry->fid, __entry->command) 1392 1392 ) 1393 1393 1394 1394 #define DEFINE_SMB3_IOCTL_EVENT(name) \ ··· 1400 1400 1401 1401 DEFINE_SMB3_IOCTL_EVENT(ioctl); 1402 1402 1403 + DECLARE_EVENT_CLASS(smb3_shutdown_class, 1404 + TP_PROTO(__u32 flags, 1405 + __u32 tid), 1406 + TP_ARGS(flags, tid), 1407 + TP_STRUCT__entry( 1408 + __field(__u32, flags) 1409 + __field(__u32, tid) 1410 + ), 1411 + TP_fast_assign( 1412 + __entry->flags = flags; 1413 + __entry->tid = tid; 1414 + ), 1415 + TP_printk("flags=0x%x tid=0x%x", 1416 + __entry->flags, __entry->tid) 1417 + ) 1403 1418 1419 + #define DEFINE_SMB3_SHUTDOWN_EVENT(name) \ 1420 + DEFINE_EVENT(smb3_shutdown_class, smb3_##name, \ 1421 + TP_PROTO(__u32 flags, \ 1422 + __u32 tid), \ 1423 + TP_ARGS(flags, tid)) 1404 1424 1425 + DEFINE_SMB3_SHUTDOWN_EVENT(shutdown_enter); 1426 + DEFINE_SMB3_SHUTDOWN_EVENT(shutdown_done); 1405 1427 1428 + DECLARE_EVENT_CLASS(smb3_shutdown_err_class, 1429 + TP_PROTO(int rc, 1430 + __u32 flags, 1431 + __u32 tid), 1432 + TP_ARGS(rc, flags, tid), 1433 + TP_STRUCT__entry( 1434 + __field(int, rc) 1435 + __field(__u32, flags) 1436 + __field(__u32, tid) 1437 + ), 1438 + TP_fast_assign( 1439 + __entry->rc = rc; 1440 + __entry->flags = flags; 1441 + __entry->tid = tid; 1442 + ), 1443 + TP_printk("rc=%d flags=0x%x tid=0x%x", 1444 + __entry->rc, __entry->flags, __entry->tid) 1445 + ) 1446 + 1447 + #define DEFINE_SMB3_SHUTDOWN_ERR_EVENT(name) \ 1448 + DEFINE_EVENT(smb3_shutdown_err_class, smb3_##name, \ 1449 + TP_PROTO(int rc, \ 1450 + __u32 flags, \ 1451 + __u32 tid), \ 1452 + TP_ARGS(rc, flags, tid)) 1453 + 1454 + DEFINE_SMB3_SHUTDOWN_ERR_EVENT(shutdown_err); 1406 1455 1407 1456 DECLARE_EVENT_CLASS(smb3_credit_class, 1408 1457 TP_PROTO(__u64 currmid,