Skip to content

Commit 3f3f6d6

Browse files
committed
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
2 parents 3c41df4 + a91bfa6 commit 3f3f6d6

File tree

10 files changed

+119
-96
lines changed

10 files changed

+119
-96
lines changed

fs/smb/client/cifsfs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,6 @@ extern const struct export_operations cifs_export_ops;
147147
#endif /* CONFIG_CIFS_NFSD_EXPORT */
148148

149149
/* 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"
152152
#endif /* _CIFSFS_H */

fs/smb/client/cifsglob.h

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1471,29 +1471,6 @@ struct cifs_io_parms {
14711471
struct TCP_Server_Info *server;
14721472
};
14731473

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-
14971474
struct cifs_io_request {
14981475
struct netfs_io_request rreq;
14991476
struct cifsFileInfo *cfile;
@@ -2010,7 +1987,6 @@ require use of the stronger protocol */
20101987
* cifsFileInfo->file_info_lock cifsFileInfo->count cifs_new_fileinfo
20111988
* ->invalidHandle initiate_cifs_search
20121989
* ->oplock_break_cancelled
2013-
* cifs_aio_ctx->aio_mutex cifs_aio_ctx cifs_aio_ctx_alloc
20141990
****************************************************************************/
20151991

20161992
#ifdef DECLARE_GLOBALS_HERE

fs/smb/client/cifsproto.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -619,8 +619,6 @@ int __cifs_calc_signature(struct smb_rqst *rqst,
619619
struct shash_desc *shash);
620620
enum securityEnum cifs_select_sectype(struct TCP_Server_Info *,
621621
enum securityEnum);
622-
struct cifs_aio_ctx *cifs_aio_ctx_alloc(void);
623-
void cifs_aio_ctx_release(struct kref *refcount);
624622

625623
int cifs_alloc_hash(const char *name, struct shash_desc **sdesc);
626624
void cifs_free_hash(struct shash_desc **sdesc);

fs/smb/client/inode.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,13 +1042,26 @@ static int reparse_info_to_fattr(struct cifs_open_info_data *data,
10421042
}
10431043

10441044
rc = -EOPNOTSUPP;
1045-
switch ((data->reparse.tag = tag)) {
1046-
case 0: /* SMB1 symlink */
1045+
data->reparse.tag = tag;
1046+
if (!data->reparse.tag) {
10471047
if (server->ops->query_symlink) {
10481048
rc = server->ops->query_symlink(xid, tcon,
10491049
cifs_sb, full_path,
10501050
&data->symlink_target);
10511051
}
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;
1064+
}
10521065
break;
10531066
case IO_REPARSE_TAG_MOUNT_POINT:
10541067
cifs_create_junction_fattr(fattr, sb);

fs/smb/client/ioctl.c

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -170,22 +170,32 @@ static long smb_mnt_get_fsinfo(unsigned int xid, struct cifs_tcon *tcon,
170170
static int cifs_shutdown(struct super_block *sb, unsigned long arg)
171171
{
172172
struct cifs_sb_info *sbi = CIFS_SB(sb);
173+
struct tcon_link *tlink;
174+
struct cifs_tcon *tcon;
173175
__u32 flags;
176+
int rc;
174177

175178
if (!capable(CAP_SYS_ADMIN))
176179
return -EPERM;
177180

178181
if (get_user(flags, (__u32 __user *)arg))
179182
return -EFAULT;
180183

181-
if (flags > CIFS_GOING_FLAGS_NOLOGFLUSH)
182-
return -EINVAL;
184+
tlink = cifs_sb_tlink(sbi);
185+
if (IS_ERR(tlink))
186+
return PTR_ERR(tlink);
187+
tcon = tlink_tcon(tlink);
188+
189+
trace_smb3_shutdown_enter(flags, tcon->tid);
190+
if (flags > CIFS_GOING_FLAGS_NOLOGFLUSH) {
191+
rc = -EINVAL;
192+
goto shutdown_out_err;
193+
}
183194

184195
if (cifs_forced_shutdown(sbi))
185-
return 0;
196+
goto shutdown_good;
186197

187198
cifs_dbg(VFS, "shut down requested (%d)", flags);
188-
/* trace_cifs_shutdown(sb, flags);*/
189199

190200
/*
191201
* see:
@@ -201,7 +211,8 @@ static int cifs_shutdown(struct super_block *sb, unsigned long arg)
201211
*/
202212
case CIFS_GOING_FLAGS_DEFAULT:
203213
cifs_dbg(FYI, "shutdown with default flag not supported\n");
204-
return -EINVAL;
214+
rc = -EINVAL;
215+
goto shutdown_out_err;
205216
/*
206217
* FLAGS_LOGFLUSH is easy since it asks to write out metadata (not
207218
* data) but metadata writes are not cached on the client, so can treat
@@ -210,11 +221,18 @@ static int cifs_shutdown(struct super_block *sb, unsigned long arg)
210221
case CIFS_GOING_FLAGS_LOGFLUSH:
211222
case CIFS_GOING_FLAGS_NOLOGFLUSH:
212223
sbi->mnt_cifs_flags |= CIFS_MOUNT_SHUTDOWN;
213-
return 0;
224+
goto shutdown_good;
214225
default:
215-
return -EINVAL;
226+
rc = -EINVAL;
227+
goto shutdown_out_err;
216228
}
229+
230+
shutdown_good:
231+
trace_smb3_shutdown_done(flags, tcon->tid);
217232
return 0;
233+
shutdown_out_err:
234+
trace_smb3_shutdown_err(rc, flags, tcon->tid);
235+
return rc;
218236
}
219237

220238
static int cifs_dump_full_key(struct cifs_tcon *tcon, struct smb3_full_key_debug_info __user *in)

fs/smb/client/misc.c

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -995,60 +995,6 @@ parse_dfs_referrals(struct get_dfs_referral_rsp *rsp, u32 rsp_size,
995995
return rc;
996996
}
997997

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-
1052998
/**
1053999
* cifs_alloc_hash - allocate hash and hash context together
10541000
* @name: The name of the crypto hash algo

fs/smb/client/reparse.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,10 @@ bool cifs_reparse_point_to_fattr(struct cifs_sb_info *cifs_sb,
505505
}
506506

507507
switch (tag) {
508+
case IO_REPARSE_TAG_INTERNAL:
509+
if (!(fattr->cf_cifsattrs & ATTR_DIRECTORY))
510+
return false;
511+
fallthrough;
508512
case IO_REPARSE_TAG_DFS:
509513
case IO_REPARSE_TAG_DFSR:
510514
case IO_REPARSE_TAG_MOUNT_POINT:

fs/smb/client/reparse.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@
1212
#include "fs_context.h"
1313
#include "cifsglob.h"
1414

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+
1521
static inline dev_t reparse_nfs_mkdev(struct reparse_posix_data *buf)
1622
{
1723
u64 v = le64_to_cpu(*(__le64 *)buf->DataBuffer);
@@ -78,10 +84,19 @@ static inline u32 reparse_mode_wsl_tag(mode_t mode)
7884
static inline bool reparse_inode_match(struct inode *inode,
7985
struct cifs_fattr *fattr)
8086
{
87+
struct cifsInodeInfo *cinode = CIFS_I(inode);
8188
struct timespec64 ctime = inode_get_ctime(inode);
8289

83-
return (CIFS_I(inode)->cifsAttrs & ATTR_REPARSE) &&
84-
CIFS_I(inode)->reparse_tag == fattr->cf_cifstag &&
90+
/*
91+
* Do not match reparse tags when client or server doesn't support
92+
* FSCTL_GET_REPARSE_POINT. @fattr->cf_cifstag should contain correct
93+
* reparse tag from query dir response but the client won't be able to
94+
* read the reparse point data anyway. This spares us a revalidation.
95+
*/
96+
if (cinode->reparse_tag != IO_REPARSE_TAG_INTERNAL &&
97+
cinode->reparse_tag != fattr->cf_cifstag)
98+
return false;
99+
return (cinode->cifsAttrs & ATTR_REPARSE) &&
85100
timespec64_equal(&ctime, &fattr->cf_ctime);
86101
}
87102

fs/smb/client/smb2inode.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,8 @@ int smb2_query_path_info(const unsigned int xid,
930930

931931
switch (rc) {
932932
case 0:
933+
rc = parse_create_response(data, cifs_sb, &out_iov[0]);
934+
break;
933935
case -EOPNOTSUPP:
934936
/*
935937
* BB TODO: When support for special files added to Samba
@@ -948,7 +950,8 @@ int smb2_query_path_info(const unsigned int xid,
948950
cmds[num_cmds++] = SMB2_OP_GET_REPARSE;
949951

950952
oparms = CIFS_OPARMS(cifs_sb, tcon, full_path,
951-
FILE_READ_ATTRIBUTES | FILE_READ_EA,
953+
FILE_READ_ATTRIBUTES |
954+
FILE_READ_EA | SYNCHRONIZE,
952955
FILE_OPEN, create_options |
953956
OPEN_REPARSE_POINT, ACL_NO_MODE);
954957
cifs_get_readable_path(tcon, full_path, &cfile);
@@ -1256,7 +1259,8 @@ int smb2_query_reparse_point(const unsigned int xid,
12561259
cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path);
12571260

12581261
cifs_get_readable_path(tcon, full_path, &cfile);
1259-
oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, FILE_READ_ATTRIBUTES,
1262+
oparms = CIFS_OPARMS(cifs_sb, tcon, full_path,
1263+
FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE,
12601264
FILE_OPEN, OPEN_REPARSE_POINT, ACL_NO_MODE);
12611265
rc = smb2_compound_op(xid, tcon, cifs_sb,
12621266
full_path, &oparms, &in_iov,

fs/smb/client/trace.h

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1388,7 +1388,7 @@ DECLARE_EVENT_CLASS(smb3_ioctl_class,
13881388
__entry->command = command;
13891389
),
13901390
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)
13921392
)
13931393

13941394
#define DEFINE_SMB3_IOCTL_EVENT(name) \
@@ -1400,9 +1400,58 @@ DEFINE_EVENT(smb3_ioctl_class, smb3_##name, \
14001400

14011401
DEFINE_SMB3_IOCTL_EVENT(ioctl);
14021402

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+
)
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))
1424+
1425+
DEFINE_SMB3_SHUTDOWN_EVENT(shutdown_enter);
1426+
DEFINE_SMB3_SHUTDOWN_EVENT(shutdown_done);
14031427

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+
)
14041446

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))
14051453

1454+
DEFINE_SMB3_SHUTDOWN_ERR_EVENT(shutdown_err);
14061455

14071456
DECLARE_EVENT_CLASS(smb3_credit_class,
14081457
TP_PROTO(__u64 currmid,

0 commit comments

Comments
 (0)