From 472697f67cf64a2461ad1842927f3c8cc539f37e Mon Sep 17 00:00:00 2001 From: Henrique Carvalho Date: Tue, 12 Nov 2024 16:48:09 -0300 Subject: smb: client: replace function pointers of common operations for the common function Signed-off-by: Henrique Carvalho --- fs/smb/client/cached_dir.c | 5 +- fs/smb/client/cifs_debug.c | 12 +- fs/smb/client/cifsacl.c | 24 +-- fs/smb/client/cifsfs.c | 22 +- fs/smb/client/cifsglob.h | 478 ++++++++++++++++++------------------------ fs/smb/client/connect.c | 100 +++------ fs/smb/client/dfs.c | 15 +- fs/smb/client/dfs_cache.c | 4 +- fs/smb/client/dir.c | 32 +-- fs/smb/client/file.c | 97 ++++----- fs/smb/client/inode.c | 54 ++--- fs/smb/client/ioctl.c | 10 +- fs/smb/client/link.c | 8 +- fs/smb/client/misc.c | 2 +- fs/smb/client/readdir.c | 12 +- fs/smb/client/reparse.c | 8 +- fs/smb/client/smb2inode.c | 2 +- fs/smb/client/smb2ops.c | 308 ++------------------------- fs/smb/client/smb2pdu.c | 2 +- fs/smb/client/smb2transport.c | 2 +- fs/smb/client/tmp | 89 ++++++++ fs/smb/client/tmp2 | 292 ++++++++++++++++++++++++++ fs/smb/client/tmp3 | 168 +++++++++++++++ fs/smb/client/trace.h | 2 +- fs/smb/client/transport.c | 24 +-- fs/smb/client/xattr.c | 70 ++----- 26 files changed, 954 insertions(+), 888 deletions(-) create mode 100644 fs/smb/client/tmp create mode 100644 fs/smb/client/tmp2 create mode 100644 fs/smb/client/tmp3 diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c index a4c3cad35c41..b41243781921 100644 --- a/fs/smb/client/cached_dir.c +++ b/fs/smb/client/cached_dir.c @@ -162,9 +162,6 @@ replay_again: oplock = SMB2_OPLOCK_LEVEL_II; server = cifs_pick_channel(ses); - if (!server->ops->new_lease_key) - return -EIO; - utf16_path = cifs_convert_path_to_utf16(path, cifs_sb); if (!utf16_path) return -ENOMEM; @@ -223,7 +220,7 @@ replay_again: flags |= CIFS_TRANSFORM_REQ; pfid = &cfid->fid; - server->ops->new_lease_key(pfid); + smb2_new_lease_key(pfid); memset(rqst, 0, sizeof(rqst)); resp_buftype[0] = resp_buftype[1] = CIFS_NO_BUFFER; diff --git a/fs/smb/client/cifs_debug.c b/fs/smb/client/cifs_debug.c index 5f2b15e24bd9..f78e197327b5 100644 --- a/fs/smb/client/cifs_debug.c +++ b/fs/smb/client/cifs_debug.c @@ -44,9 +44,9 @@ static void cifs_dump_detail(void *buf, struct TCP_Server_Info *server) smb->Command, smb->Status, smb->Flags, smb->MessageId, smb->Id.SyncId.ProcessId, smb->StructureSize); - if (!server->ops->check_message(buf, server->total_read, server)) { + if (!smb2_check_message(buf, server->total_read, server)) { cifs_dbg(VFS, "smb buf %p len %u\n", smb, - server->ops->calc_smb_size(smb)); + smb2_calc_smb_size(smb)); } #endif /* CONFIG_CIFS_DEBUG2 */ } @@ -510,7 +510,7 @@ skip_rdma: spin_unlock(&ses->ses_lock); seq_printf(m, "\n\tSecurity type: %s ", - get_security_type_str(server->ops->select_sectype(server, ses->sectype))); + get_security_type_str(smb2_select_sectype(server, ses->sectype))); /* dump session id helpful for use with network trace */ seq_printf(m, " SessionId: 0x%llx", ses->Suid); @@ -682,8 +682,7 @@ static ssize_t cifs_stats_proc_write(struct file *file, tcon->bytes_written = 0; tcon->stats_from_time = ktime_get_real_seconds(); spin_unlock(&tcon->stat_lock); - if (server->ops->clear_stats) - server->ops->clear_stats(tcon); + smb2_clear_stats(tcon); } } } @@ -764,8 +763,7 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v) seq_printf(m, "\nSMBs: %d since %ptTs UTC", atomic_read(&tcon->num_smbs_sent), &tcon->stats_from_time); - if (server->ops->print_stats) - server->ops->print_stats(m, tcon); + smb2_print_stats(m, tcon); } } } diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c index 6164c35ea6b8..114dd27ee918 100644 --- a/fs/smb/client/cifsacl.c +++ b/fs/smb/client/cifsacl.c @@ -1395,7 +1395,6 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, u32 acllen = 0; int rc = 0; struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); - struct smb_version_operations *ops; const u32 info = 0; cifs_dbg(NOISY, "converting ACL to mode for %s\n", path); @@ -1403,16 +1402,11 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, if (IS_ERR(tlink)) return PTR_ERR(tlink); - ops = tlink_tcon(tlink)->ses->server->ops; + if (pfid) + pntsd = get_smb2_acl_by_fid(cifs_sb, pfid, &acllen, info); + else + pntsd = get_smb2_acl(cifs_sb, inode, path, &acllen, info); - if (pfid && (ops->get_acl_by_fid)) - pntsd = ops->get_acl_by_fid(cifs_sb, pfid, &acllen, info); - else if (ops->get_acl) - pntsd = ops->get_acl(cifs_sb, inode, path, &acllen, info); - else { - cifs_put_tlink(tlink); - return -EOPNOTSUPP; - } /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */ if (IS_ERR(pntsd)) { rc = PTR_ERR(pntsd); @@ -1448,25 +1442,17 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode, struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */ struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); - struct smb_version_operations *ops; bool mode_from_sid, id_from_sid; const u32 info = 0; if (IS_ERR(tlink)) return PTR_ERR(tlink); - ops = tlink_tcon(tlink)->ses->server->ops; - cifs_dbg(NOISY, "set ACL from mode for %s\n", path); /* Get the security descriptor */ - if (ops->get_acl == NULL) { - cifs_put_tlink(tlink); - return -EOPNOTSUPP; - } - - pntsd = ops->get_acl(cifs_sb, inode, path, &secdesclen, info); + pntsd = get_smb2_acl(cifs_sb, inode, path, &secdesclen, info); if (IS_ERR(pntsd)) { rc = PTR_ERR(pntsd); cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc); diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c index 49e2e2bf45e6..c6f517099eea 100644 --- a/fs/smb/client/cifsfs.c +++ b/fs/smb/client/cifsfs.c @@ -1016,9 +1016,7 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int whence) } if (cfile && cfile->tlink) { tcon = tlink_tcon(cfile->tlink); - if (tcon->ses->server->ops->llseek) - return tcon->ses->server->ops->llseek(file, tcon, - offset, whence); + return smb3_llseek(file, tcon, offset, whence); } return generic_file_llseek(file, offset, whence); } @@ -1149,12 +1147,8 @@ static int cifs_precopy_set_eof(struct inode *src_inode, struct cifsInodeInfo *s writeable_srcfile = find_writable_file(src_cifsi, FIND_WR_FSUID_ONLY); if (writeable_srcfile) { - if (src_tcon->ses->server->ops->set_file_size) - rc = src_tcon->ses->server->ops->set_file_size( - xid, src_tcon, writeable_srcfile, - src_inode->i_size, true /* no need to set sparse */); - else - rc = -ENOSYS; + rc = smb2_set_file_size(xid, src_tcon, writeable_srcfile, src_inode->i_size, + true /* no need to set sparse */); cifsFileInfo_put(writeable_srcfile); cifs_dbg(FYI, "SetFSize for copychunk rc = %d\n", rc); } @@ -1349,10 +1343,6 @@ ssize_t cifs_file_copychunk_range(unsigned int xid, goto out; } - rc = -EOPNOTSUPP; - if (!target_tcon->ses->server->ops->copychunk_range) - goto out; - /* * Note: cifs case is easier than btrfs since server responsible for * checks for proper open modes and file type and if it wants @@ -1390,8 +1380,7 @@ ssize_t cifs_file_copychunk_range(unsigned int xid, rc = file_modified(dst_file); if (!rc) { - rc = target_tcon->ses->server->ops->copychunk_range(xid, - smb_file_src, smb_file_target, off, len, destoff); + rc = smb2_copychunk_range(xid, smb_file_src, smb_file_target, off, len, destoff); if (rc > 0 && destoff + rc > i_size_read(target_inode)) { truncate_setsize(target_inode, destoff + rc); netfs_resize_file(&target_cifsi->netfs, @@ -1446,8 +1435,7 @@ static ssize_t cifs_copy_file_range(struct file *src_file, loff_t off, return rc; } - rc = cifs_file_copychunk_range(xid, src_file, off, dst_file, destoff, - len, flags); + rc = cifs_file_copychunk_range(xid, src_file, off, dst_file, destoff, len, flags); free_xid(xid); if (rc == -EOPNOTSUPP || rc == -EXDEV) diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index f519e8c9a81f..ef81676664a5 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -274,329 +274,277 @@ struct cifsInodeInfo; struct cifs_open_parms; struct cifs_credits; -struct smb_version_operations { - int (*send_cancel)(struct TCP_Server_Info *, struct smb_rqst *, - struct mid_q_entry *); - bool (*compare_fids)(struct cifsFileInfo *, struct cifsFileInfo *); - /* setup request: allocate mid, sign message */ - struct mid_q_entry *(*setup_request)(struct cifs_ses *, - struct TCP_Server_Info *, - struct smb_rqst *); - /* setup async request: allocate mid, sign message */ - struct mid_q_entry *(*setup_async_request)(struct TCP_Server_Info *, - struct smb_rqst *); - /* check response: verify signature, map error */ - int (*check_receive)(struct mid_q_entry *, struct TCP_Server_Info *, - bool); - void (*add_credits)(struct TCP_Server_Info *server, - struct cifs_credits *credits, - const int optype); - void (*set_credits)(struct TCP_Server_Info *, const int); - int * (*get_credits_field)(struct TCP_Server_Info *, const int); - unsigned int (*get_credits)(struct mid_q_entry *); - __u64 (*get_next_mid)(struct TCP_Server_Info *); - void (*revert_current_mid)(struct TCP_Server_Info *server, - const unsigned int val); - /* data offset from read response message */ - unsigned int (*read_data_offset)(char *); - /* - * Data length from read response message - * When in_remaining is true, the returned data length is in - * message field DataRemaining for out-of-band data read (e.g through - * Memory Registration RDMA write in SMBD). - * Otherwise, the returned data length is in message field DataLength. - */ - unsigned int (*read_data_length)(char *, bool in_remaining); - /* map smb to linux error */ - int (*map_error)(char *, bool); - /* find mid corresponding to the response message */ - struct mid_q_entry * (*find_mid)(struct TCP_Server_Info *, char *); - void (*dump_detail)(void *buf, struct TCP_Server_Info *ptcp_info); - void (*clear_stats)(struct cifs_tcon *); - void (*print_stats)(struct seq_file *m, struct cifs_tcon *); - void (*dump_share_caps)(struct seq_file *, struct cifs_tcon *); - /* verify the message */ - int (*check_message)(char *, unsigned int, struct TCP_Server_Info *); - bool (*is_oplock_break)(char *, struct TCP_Server_Info *); - int (*handle_cancelled_mid)(struct mid_q_entry *, struct TCP_Server_Info *); - void (*downgrade_oplock)(struct TCP_Server_Info *server, - struct cifsInodeInfo *cinode, __u32 oplock, - unsigned int epoch, bool *purge_cache); - /* process transaction2 response */ - bool (*check_trans2)(struct mid_q_entry *, struct TCP_Server_Info *, - char *, int); - /* check if we need to negotiate */ - bool (*need_neg)(struct TCP_Server_Info *); - /* negotiate to the server */ - int (*negotiate)(const unsigned int xid, - struct cifs_ses *ses, - struct TCP_Server_Info *server); - /* set negotiated write size */ - unsigned int (*negotiate_wsize)(struct cifs_tcon *tcon, struct smb3_fs_context *ctx); - /* set negotiated read size */ - unsigned int (*negotiate_rsize)(struct cifs_tcon *tcon, struct smb3_fs_context *ctx); - /* setup smb sessionn */ - int (*sess_setup)(const unsigned int, struct cifs_ses *, - struct TCP_Server_Info *server, - const struct nls_table *); - /* close smb session */ - int (*logoff)(const unsigned int, struct cifs_ses *); - /* connect to a server share */ - int (*tree_connect)(const unsigned int, struct cifs_ses *, const char *, - struct cifs_tcon *, const struct nls_table *); - /* close tree connection */ - int (*tree_disconnect)(const unsigned int, struct cifs_tcon *); - /* get DFS referrals */ - int (*get_dfs_refer)(const unsigned int, struct cifs_ses *, - const char *, struct dfs_info3_param **, - unsigned int *, const struct nls_table *, int); - /* informational QFS call */ - void (*qfs_tcon)(const unsigned int, struct cifs_tcon *, - struct cifs_sb_info *); - /* query for server interfaces */ - int (*query_server_interfaces)(const unsigned int, struct cifs_tcon *, - bool); - /* check if a path is accessible or not */ - int (*is_path_accessible)(const unsigned int, struct cifs_tcon *, - struct cifs_sb_info *, const char *); - /* query path data from the server */ - int (*query_path_info)(const unsigned int xid, - struct cifs_tcon *tcon, - struct cifs_sb_info *cifs_sb, - const char *full_path, - struct cifs_open_info_data *data); - /* query file data from the server */ - int (*query_file_info)(const unsigned int xid, struct cifs_tcon *tcon, +/* TODO: find a suitable place for these functions */ +extern struct mid_q_entry * smb2_find_mid(struct TCP_Server_Info *, char *); +extern void smb2_dump_detail(void *buf, struct TCP_Server_Info *ptcp_info); +extern void clear_stats(struct cifs_tcon *); +extern void smb2_print_stats(struct seq_file *m, struct cifs_tcon *); +extern bool smb2_is_valid_oplock_break(char *, struct TCP_Server_Info *); +extern int smb2_handle_cancelled_mid(struct mid_q_entry *, struct TCP_Server_Info *); +extern bool smb2_need_neg(struct TCP_Server_Info *); +extern int smb2_negotiate(const unsigned int xid, + struct cifs_ses *ses, + struct TCP_Server_Info *server); +extern int SMB2_sess_setup(const unsigned int, struct cifs_ses *, + struct TCP_Server_Info *server, + const struct nls_table *); +extern int SMB2_logoff(const unsigned int, struct cifs_ses *); +/* connect to a server share */ +extern int SMB2_tcon(const unsigned int, struct cifs_ses *, const char *, + struct cifs_tcon *, const struct nls_table *); +/* close tree connection */ +extern int SMB2_tdis(const unsigned int, struct cifs_tcon *); + + +extern int smb2_get_dfs_refer(const unsigned int, struct cifs_ses *, + const char *, struct dfs_info3_param **, + unsigned int *, const struct nls_table *, int); +/* check if a path is accessible or not */ +extern int smb2_is_path_accessible(const unsigned int, struct cifs_tcon *, + struct cifs_sb_info *, const char *); +/* query path data from the server */ +extern int smb2_query_path_info(const unsigned int xid, + struct cifs_tcon *tcon, + struct cifs_sb_info *cifs_sb, + const char *full_path, + struct cifs_open_info_data *data); +/* query reparse point to determine which type of special file */ +extern int smb2_query_reparse_point(const unsigned int xid, + struct cifs_tcon *tcon, + struct cifs_sb_info *cifs_sb, + const char *full_path, + u32 *tag, struct kvec *rsp, + int *rsp_buftype); +/* get server index number */ +extern int smb2_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon, + struct cifs_sb_info *cifs_sb, const char *full_path, u64 *uniqueid, + struct cifs_open_info_data *data); +/* query file data from the server */ +extern int smb2_query_file_info(const unsigned int xid, struct cifs_tcon *tcon, struct cifsFileInfo *cfile, struct cifs_open_info_data *data); - /* query reparse point to determine which type of special file */ - int (*query_reparse_point)(const unsigned int xid, - struct cifs_tcon *tcon, - struct cifs_sb_info *cifs_sb, - const char *full_path, - u32 *tag, struct kvec *rsp, - int *rsp_buftype); - /* get server index number */ - int (*get_srv_inum)(const unsigned int xid, struct cifs_tcon *tcon, - struct cifs_sb_info *cifs_sb, const char *full_path, u64 *uniqueid, - struct cifs_open_info_data *data); - /* set size by path */ - int (*set_path_size)(const unsigned int, struct cifs_tcon *, +/* set size by path */ +extern int smb2_set_path_size(const unsigned int, struct cifs_tcon *, const char *, __u64, struct cifs_sb_info *, bool, struct dentry *); - /* set size by file handle */ - int (*set_file_size)(const unsigned int, struct cifs_tcon *, - struct cifsFileInfo *, __u64, bool); - /* set attributes */ - int (*set_file_info)(struct inode *, const char *, FILE_BASIC_INFO *, - const unsigned int); - int (*set_compression)(const unsigned int, struct cifs_tcon *, +/* set size by file handle */ +extern int smb2_set_file_size(const unsigned int, struct cifs_tcon *, + struct cifsFileInfo *, __u64, bool); +/* set attributes */ +int smb2_set_file_info(struct inode *, const char *, FILE_BASIC_INFO *, + const unsigned int); +extern int smb2_set_compression(const unsigned int, struct cifs_tcon *, struct cifsFileInfo *); - /* check if we can send an echo or nor */ - bool (*can_echo)(struct TCP_Server_Info *); - /* send echo request */ - int (*echo)(struct TCP_Server_Info *); - /* create directory */ - int (*posix_mkdir)(const unsigned int xid, struct inode *inode, - umode_t mode, struct cifs_tcon *tcon, - const char *full_path, - struct cifs_sb_info *cifs_sb); - int (*mkdir)(const unsigned int xid, struct inode *inode, umode_t mode, +/* check if we can send an echo or nor */ +extern bool smb2_can_echo(struct TCP_Server_Info *); +/* send echo request */ +extern int SMB2_echo(struct TCP_Server_Info *); +extern int smb2_mkdir(const unsigned int xid, struct inode *inode, umode_t mode, struct cifs_tcon *tcon, const char *name, struct cifs_sb_info *sb); - /* set info on created directory */ - void (*mkdir_setinfo)(struct inode *, const char *, +/* set info on created directory */ +extern void smb2_mkdir_setinfo(struct inode *, const char *, struct cifs_sb_info *, struct cifs_tcon *, const unsigned int); - /* remove directory */ - int (*rmdir)(const unsigned int, struct cifs_tcon *, const char *, +/* remove directory */ +extern int smb2_rmdir(const unsigned int, struct cifs_tcon *, const char *, struct cifs_sb_info *); - /* unlink file */ - int (*unlink)(const unsigned int, struct cifs_tcon *, const char *, +/* unlink file */ +extern int smb2_unlink(const unsigned int, struct cifs_tcon *, const char *, struct cifs_sb_info *, struct dentry *); - /* open, rename and delete file */ - int (*rename_pending_delete)(const char *, struct dentry *, - const unsigned int); - /* send rename request */ - int (*rename)(const unsigned int xid, +/* send rename request */ +extern int smb2_rename_path(const unsigned int xid, struct cifs_tcon *tcon, struct dentry *source_dentry, const char *from_name, const char *to_name, struct cifs_sb_info *cifs_sb); - /* send create hardlink request */ - int (*create_hardlink)(const unsigned int xid, +extern int smb2_create_hardlink(const unsigned int xid, struct cifs_tcon *tcon, struct dentry *source_dentry, const char *from_name, const char *to_name, struct cifs_sb_info *cifs_sb); - /* query symlink target */ - int (*query_symlink)(const unsigned int xid, - struct cifs_tcon *tcon, - struct cifs_sb_info *cifs_sb, - const char *full_path, - char **target_path); - /* open a file for non-posix mounts */ - int (*open)(const unsigned int xid, struct cifs_open_parms *oparms, __u32 *oplock, +/* open a file for non-posix mounts */ +extern int smb2_open(const unsigned int xid, struct cifs_open_parms *oparms, __u32 *oplock, void *buf); - /* set fid protocol-specific info */ - void (*set_fid)(struct cifsFileInfo *, struct cifs_fid *, __u32); - /* close a file */ - int (*close)(const unsigned int, struct cifs_tcon *, +/* set fid protocol-specific info */ +extern void smb2_set_fid(struct cifsFileInfo *, struct cifs_fid *, __u32); +/* close a file */ +extern int smb2_close(const unsigned int, struct cifs_tcon *, struct cifs_fid *); - /* close a file, returning file attributes and timestamps */ - int (*close_getattr)(const unsigned int xid, struct cifs_tcon *tcon, - struct cifsFileInfo *pfile_info); - /* send a flush request to the server */ - int (*flush)(const unsigned int, struct cifs_tcon *, struct cifs_fid *); - /* async read from the server */ - int (*async_readv)(struct cifs_io_subrequest *); - /* async write to the server */ - void (*async_writev)(struct cifs_io_subrequest *); - /* sync read from the server */ - int (*sync_read)(const unsigned int, struct cifs_fid *, +/* send a flush request to the server */ +extern int smb2_flush_file(const unsigned int, struct cifs_tcon *, struct cifs_fid *); +/* async read from the server */ +extern int smb2_async_readv(struct cifs_io_subrequest *); +/* async write to the server */ +extern void smb2_async_writev(struct cifs_io_subrequest *); +/* sync read from the server */ +extern int smb2_sync_read(const unsigned int, struct cifs_fid *, struct cifs_io_parms *, unsigned int *, char **, int *); - /* sync write to the server */ - int (*sync_write)(const unsigned int, struct cifs_fid *, +/* sync write to the server */ +extern int smb2_sync_write(const unsigned int, struct cifs_fid *, struct cifs_io_parms *, unsigned int *, struct kvec *, unsigned long); - /* open dir, start readdir */ - int (*query_dir_first)(const unsigned int, struct cifs_tcon *, +/* open dir, start readdir */ +extern int smb2_query_dir_first(const unsigned int, struct cifs_tcon *, const char *, struct cifs_sb_info *, struct cifs_fid *, __u16, struct cifs_search_info *); - /* continue readdir */ - int (*query_dir_next)(const unsigned int, struct cifs_tcon *, +/* continue readdir */ +extern int smb2_query_dir_next(const unsigned int, struct cifs_tcon *, struct cifs_fid *, __u16, struct cifs_search_info *srch_inf); - /* close dir */ - int (*close_dir)(const unsigned int, struct cifs_tcon *, +/* close dir */ +extern int smb2_close_dir(const unsigned int, struct cifs_tcon *, struct cifs_fid *); - /* calculate a size of SMB message */ - unsigned int (*calc_smb_size)(void *buf); - /* check for STATUS_PENDING and process the response if yes */ - bool (*is_status_pending)(char *buf, struct TCP_Server_Info *server); - /* check for STATUS_NETWORK_SESSION_EXPIRED */ - bool (*is_session_expired)(char *); - /* send oplock break response */ - int (*oplock_response)(struct cifs_tcon *tcon, __u64 persistent_fid, __u64 volatile_fid, +/* calculate a size of SMB message */ +extern unsigned int smb2_calc_size(void *buf); +/* check for STATUS_PENDING and process the response if yes */ +extern bool smb2_is_status_pending(char *buf, struct TCP_Server_Info *server); +/* check for STATUS_NETWORK_SESSION_EXPIRED */ +extern bool smb2_is_session_expired(char *); +/* send oplock break response */ +extern int smb2_oplock_response(struct cifs_tcon *tcon, __u64 persistent_fid, __u64 volatile_fid, __u16 net_fid, struct cifsInodeInfo *cifs_inode); - /* query remote filesystem */ - int (*queryfs)(const unsigned int, struct cifs_tcon *, - const char *, struct cifs_sb_info *, struct kstatfs *); - /* send mandatory brlock to the server */ - int (*mand_lock)(const unsigned int, struct cifsFileInfo *, __u64, +/* send mandatory brlock to the server */ +extern int smb2_mand_lock(const unsigned int, struct cifsFileInfo *, __u64, __u64, __u32, int, int, bool); - /* unlock range of mandatory locks */ - int (*mand_unlock_range)(struct cifsFileInfo *, struct file_lock *, +/* unlock range of mandatory locks */ +extern int smb2_unlock_range(struct cifsFileInfo *, struct file_lock *, const unsigned int); - /* push brlocks from the cache to the server */ - int (*push_mand_locks)(struct cifsFileInfo *); - /* get lease key of the inode */ - void (*get_lease_key)(struct inode *, struct cifs_fid *); - /* set lease key of the inode */ - void (*set_lease_key)(struct inode *, struct cifs_fid *); - /* generate new lease key */ - void (*new_lease_key)(struct cifs_fid *); - int (*generate_signingkey)(struct cifs_ses *ses, - struct TCP_Server_Info *server); - int (*calc_signature)(struct smb_rqst *, struct TCP_Server_Info *, - bool allocate_crypto); - int (*set_integrity)(const unsigned int, struct cifs_tcon *tcon, - struct cifsFileInfo *src_file); - int (*enum_snapshots)(const unsigned int xid, struct cifs_tcon *tcon, + +/* push brlocks from the cache to the server */ +extern int smb2_push_mandatory_locks(struct cifsFileInfo *); +/* get lease key of the inode */ +extern void smb2_get_lease_key(struct inode *, struct cifs_fid *); +/* set lease key of the inode */ +extern void smb2_set_lease_key(struct inode *, struct cifs_fid *); +/* generate new lease key */ +extern void smb2_new_lease_key(struct cifs_fid *); +extern int smb3_enum_snapshots(const unsigned int xid, struct cifs_tcon *tcon, struct cifsFileInfo *src_file, void __user *); - int (*notify)(const unsigned int xid, struct file *pfile, +extern int smb3_notify(const unsigned int xid, struct file *pfile, void __user *pbuf, bool return_changes); - int (*query_mf_symlink)(unsigned int, struct cifs_tcon *, +extern int smb3_query_mf_symlink(unsigned int, struct cifs_tcon *, struct cifs_sb_info *, const unsigned char *, char *, unsigned int *); - int (*create_mf_symlink)(unsigned int, struct cifs_tcon *, +extern int smb3_create_mf_symlink(unsigned int, struct cifs_tcon *, struct cifs_sb_info *, const unsigned char *, char *, unsigned int *); - /* if we can do cache read operations */ - bool (*is_read_op)(__u32); - /* set oplock level for the inode */ - void (*set_oplock_level)(struct cifsInodeInfo *, __u32, unsigned int, - bool *); - /* create lease context buffer for CREATE request */ - char * (*create_lease_buf)(u8 *lease_key, u8 oplock); - /* parse lease context buffer and return oplock/epoch info */ - __u8 (*parse_lease_buf)(void *buf, unsigned int *epoch, char *lkey); - ssize_t (*copychunk_range)(const unsigned int, +/* if we can do cache read operations */ +extern bool smb21_is_read_op(__u32); +extern ssize_t copychunk_range)(const unsigned int, struct cifsFileInfo *src_file, struct cifsFileInfo *target_file, u64 src_off, u64 len, u64 dest_off); - int (*duplicate_extents)(const unsigned int, struct cifsFileInfo *src, - struct cifsFileInfo *target_file, u64 src_off, u64 len, - u64 dest_off); - int (*validate_negotiate)(const unsigned int, struct cifs_tcon *); - ssize_t (*query_all_EAs)(const unsigned int, struct cifs_tcon *, +extern ssize_t smb2_query_eas(const unsigned int, struct cifs_tcon *, const unsigned char *, const unsigned char *, char *, size_t, struct cifs_sb_info *); - int (*set_EA)(const unsigned int, struct cifs_tcon *, const char *, +extern int smb2_set_ea(const unsigned int, struct cifs_tcon *, const char *, const char *, const void *, const __u16, const struct nls_table *, struct cifs_sb_info *); - struct cifs_ntsd * (*get_acl)(struct cifs_sb_info *, struct inode *, +extern struct cifs_ntsd * get_smb2_acl(struct cifs_sb_info *, struct inode *, const char *, u32 *, u32); - struct cifs_ntsd * (*get_acl_by_fid)(struct cifs_sb_info *, +extern struct cifs_ntsd * get_smb2_acl_by_fid(struct cifs_sb_info *, const struct cifs_fid *, u32 *, u32); - int (*set_acl)(struct cifs_ntsd *, __u32, struct inode *, const char *, +extern int set_smb2_acl(struct cifs_ntsd *, __u32, struct inode *, const char *, int); /* writepages retry size */ - unsigned int (*wp_retry_size)(struct inode *); - /* get mtu credits */ - int (*wait_mtu_credits)(struct TCP_Server_Info *, size_t, - size_t *, struct cifs_credits *); - /* adjust previously taken mtu credits to request size */ - int (*adjust_credits)(struct TCP_Server_Info *server, - struct cifs_io_subrequest *subreq, - unsigned int /*enum smb3_rw_credits_trace*/ trace); +extern unsigned int smb2_wp_retry_size(struct inode *); /* check if we need to issue closedir */ - bool (*dir_needs_close)(struct cifsFileInfo *); - long (*fallocate)(struct file *, struct cifs_tcon *, int, loff_t, - loff_t); - /* init transform request - used for encryption for now */ - int (*init_transform_rq)(struct TCP_Server_Info *, int num_rqst, - struct smb_rqst *, struct smb_rqst *); - int (*is_transform_hdr)(void *buf); - int (*receive_transform)(struct TCP_Server_Info *, - struct mid_q_entry **, char **, int *); - enum securityEnum (*select_sectype)(struct TCP_Server_Info *, +extern bool smb2_dir_needs_close(struct cifsFileInfo *); +extern enum securityEnum smb2_select_sectype(struct TCP_Server_Info *, enum securityEnum); - int (*next_header)(struct TCP_Server_Info *server, char *buf, +extern int smb2_next_header(struct TCP_Server_Info *server, char *buf, unsigned int *noff); - /* ioctl passthrough for query_info */ - int (*ioctl_query_info)(const unsigned int xid, +/* ioctl passthrough for query_info */ +extern int smb2_ioctl_query_info(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb, __le16 *path, int is_dir, unsigned long p); - /* make unix special files (block, char, fifo, socket) */ - int (*make_node)(unsigned int xid, +/* make unix special files (block, char, fifo, socket) */ +extern int smb2_make_node(unsigned int xid, struct inode *inode, struct dentry *dentry, struct cifs_tcon *tcon, const char *full_path, umode_t mode, dev_t device_number); - /* version specific fiemap implementation */ - int (*fiemap)(struct cifs_tcon *tcon, struct cifsFileInfo *, +/* version specific fiemap implementation */ +extern int smb3_fiemap(struct cifs_tcon *tcon, struct cifsFileInfo *, struct fiemap_extent_info *, u64, u64); - /* version specific llseek implementation */ - loff_t (*llseek)(struct file *, struct cifs_tcon *, loff_t, int); - /* Check for STATUS_IO_TIMEOUT */ - bool (*is_status_io_timeout)(char *buf); - /* Check for STATUS_NETWORK_NAME_DELETED */ - bool (*is_network_name_deleted)(char *buf, struct TCP_Server_Info *srv); - int (*parse_reparse_point)(struct cifs_sb_info *cifs_sb, +/* version specific llseek implementation */ +extern loff_t smb3_llseek(struct file *, struct cifs_tcon *, loff_t, int); + +/* Check for STATUS_IO_TIMEOUT */ +extern bool smb2_is_status_io_timeout(char *buf); + +/* Check for STATUS_NETWORK_NAME_DELETED */ +extern bool smb2_is_network_name_deleted(char *buf, struct TCP_Server_Info *srv); + +extern int smb2_parse_reparse_point(struct cifs_sb_info *cifs_sb, struct kvec *rsp_iov, struct cifs_open_info_data *data); - int (*create_reparse_symlink)(const unsigned int xid, +extern int smb2_create_reparse_symlink(const unsigned int xid, struct inode *inode, struct dentry *dentry, struct cifs_tcon *tcon, const char *full_path, const char *symname); + +struct smb_version_operations { + /* find mid corresponding to the response message */ + void (*dump_share_caps)(struct seq_file *, struct cifs_tcon *); + /* verify the message */ + void (*downgrade_oplock)(struct TCP_Server_Info *server, + struct cifsInodeInfo *cinode, __u32 oplock, + unsigned int epoch, bool *purge_cache); + /* set negotiated write size */ + unsigned int (*negotiate_wsize)(struct cifs_tcon *tcon, struct smb3_fs_context *ctx); + /* set negotiated read size */ + unsigned int (*negotiate_rsize)(struct cifs_tcon *tcon, struct smb3_fs_context *ctx); + /* informational QFS call */ + void (*qfs_tcon)(const unsigned int, struct cifs_tcon *, + struct cifs_sb_info *); + /* query for server interfaces */ + int (*query_server_interfaces)(const unsigned int, struct cifs_tcon *, + bool); + /* create directory */ + int (*posix_mkdir)(const unsigned int xid, struct inode *inode, + umode_t mode, struct cifs_tcon *tcon, + const char *full_path, + struct cifs_sb_info *cifs_sb); /* send create hardlink request */ + /* close a file, returning file attributes and timestamps */ + int (*close_getattr)(const unsigned int xid, struct cifs_tcon *tcon, + struct cifsFileInfo *pfile_info); + /* query remote filesystem */ + int (*queryfs)(const unsigned int, struct cifs_tcon *, + const char *, struct cifs_sb_info *, struct kstatfs *); + int (*generate_signingkey)(struct cifs_ses *ses, + struct TCP_Server_Info *server); + int (*calc_signature)(struct smb_rqst *, struct TCP_Server_Info *, + bool allocate_crypto); + int (*set_integrity)(const unsigned int, struct cifs_tcon *tcon, + struct cifsFileInfo *src_file); + /* set oplock level for the inode */ + void (*set_oplock_level)(struct cifsInodeInfo *, __u32, unsigned int, + bool *); + /* create lease context buffer for CREATE request */ + char * (*create_lease_buf)(u8 *lease_key, u8 oplock); + /* parse lease context buffer and return oplock/epoch info */ + __u8 (*parse_lease_buf)(void *buf, unsigned int *epoch, char *lkey); + int (*duplicate_extents)(const unsigned int, struct cifsFileInfo *src, + struct cifsFileInfo *target_file, u64 src_off, u64 len, + u64 dest_off); + int (*validate_negotiate)(const unsigned int, struct cifs_tcon *); + long (*fallocate)(struct file *, struct cifs_tcon *, int, loff_t, + loff_t); + /* init transform request - used for encryption for now */ + int (*init_transform_rq)(struct TCP_Server_Info *, int num_rqst, + struct smb_rqst *, struct smb_rqst *); + int (*is_transform_hdr)(void *buf); + int (*receive_transform)(struct TCP_Server_Info *, + struct mid_q_entry **, char **, int *); }; struct smb_version_values { @@ -873,7 +821,7 @@ static inline void add_credits(struct TCP_Server_Info *server, struct cifs_credits *credits, const int optype) { - server->ops->add_credits(server, credits, optype); + smb2_add_credits(server, credits, optype); } static inline void @@ -881,36 +829,29 @@ add_credits_and_wake_if(struct TCP_Server_Info *server, struct cifs_credits *credits, const int optype) { if (credits->value) { - server->ops->add_credits(server, credits, optype); + smb2_add_credits(server, credits, optype); wake_up(&server->request_q); credits->value = 0; } } -static inline void -set_credits(struct TCP_Server_Info *server, const int val) -{ - server->ops->set_credits(server, val); -} - static inline int adjust_credits(struct TCP_Server_Info *server, struct cifs_io_subrequest *subreq, unsigned int /* enum smb3_rw_credits_trace */ trace) { - return server->ops->adjust_credits ? - server->ops->adjust_credits(server, subreq, trace) : 0; + return smb2_adjust_credits(server, subreq, trace) : 0; } static inline __le64 get_next_mid64(struct TCP_Server_Info *server) { - return cpu_to_le64(server->ops->get_next_mid(server)); + return cpu_to_le64(smb2_get_next_mid(server)); } static inline __le16 get_next_mid(struct TCP_Server_Info *server) { - __u16 mid = server->ops->get_next_mid(server); + __u16 mid = smb2_get_next_mid(server); /* * The value in the SMB header should be little endian for easy * on-the-wire decoding. @@ -918,20 +859,13 @@ get_next_mid(struct TCP_Server_Info *server) return cpu_to_le16(mid); } -static inline void -revert_current_mid(struct TCP_Server_Info *server, const unsigned int val) -{ - if (server->ops->revert_current_mid) - server->ops->revert_current_mid(server, val); -} - static inline void revert_current_mid_from_hdr(struct TCP_Server_Info *server, const struct smb2_hdr *shdr) { unsigned int num = le16_to_cpu(shdr->CreditCharge); - return revert_current_mid(server, num > 0 ? num : 1); + return smb2_revert_current_mid(server, num > 0 ? num : 1); } /* diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c index 89bd1b71ba2e..7dc9ea6cceb7 100644 --- a/fs/smb/client/connect.c +++ b/fs/smb/client/connect.c @@ -416,7 +416,7 @@ static int __cifs_reconnect(struct TCP_Server_Info *server, msleep(3000); } else { atomic_inc(&tcpSesReconnectCount); - set_credits(server, 1); + smb2_set_credits(server, 1); spin_lock(&server->srv_lock); if (server->tcpStatus != CifsExiting) server->tcpStatus = CifsNeedNegotiate; @@ -547,7 +547,7 @@ static int reconnect_dfs_server(struct TCP_Server_Info *server) * through the reconnected target server. */ atomic_inc(&tcpSesReconnectCount); - set_credits(server, 1); + smb2_set_credits(server, 1); spin_lock(&server->srv_lock); if (server->tcpStatus != CifsExiting) server->tcpStatus = CifsNeedNegotiate; @@ -605,11 +605,11 @@ cifs_echo_request(struct work_struct *work) if (server->tcpStatus == CifsNeedReconnect || server->tcpStatus == CifsExiting || server->tcpStatus == CifsNew || - (server->ops->can_echo && !server->ops->can_echo(server)) || + (!smb2_can_echo(server)) || time_before(jiffies, server->lstrp + server->echo_interval - HZ)) goto requeue_echo; - rc = server->ops->echo ? server->ops->echo(server) : -ENOSYS; + rc = SMB2_echo(server); cifs_server_dbg(FYI, "send echo request: rc = %d\n", rc); /* Check witness registrations */ @@ -681,7 +681,7 @@ server_unresponsive(struct TCP_Server_Info *server) */ if ((server->tcpStatus == CifsGood || server->tcpStatus == CifsNeedNegotiate) && - (!server->ops->can_echo || server->ops->can_echo(server)) && + smb2_can_echo(server) && time_after(jiffies, server->lstrp + 3 * server->echo_interval)) { spin_unlock(&server->srv_lock); cifs_server_dbg(VFS, "has not responded in %lu seconds. Reconnecting...\n", @@ -899,9 +899,6 @@ static void handle_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server, char *buf, int malformed) { - if (server->ops->check_trans2 && - server->ops->check_trans2(mid, server, buf, malformed)) - return; mid->credits_received = smb2_get_credits_from_hdr(buf, server); mid->resp_buf = buf; mid->large_buf = server->large_buf; @@ -1104,19 +1101,17 @@ cifs_handle_standard(struct TCP_Server_Info *server, struct mid_q_entry *mid) * 48 bytes is enough to display the header and a little bit * into the payload for debugging purposes. */ - rc = server->ops->check_message(buf, server->total_read, server); + rc = smb2_check_message(buf, server->total_read, server); if (rc) cifs_dump_mem("Bad SMB: ", buf, min_t(unsigned int, server->total_read, 48)); - if (server->ops->is_session_expired && - server->ops->is_session_expired(buf)) { + if (smb2_is_session_expired(buf)) { cifs_reconnect(server, true); return -1; } - if (server->ops->is_status_pending && - server->ops->is_status_pending(buf, server)) + if (smb2_is_status_pending(buf, server)) return -1; if (!mid) @@ -1220,16 +1215,14 @@ next_pdu: continue; server->total_read += length; - if (server->ops->next_header) { - if (server->ops->next_header(server, buf, &next_offset)) { - cifs_dbg(VFS, "%s: malformed response (next_offset=%u)\n", - __func__, next_offset); - cifs_reconnect(server, true); - continue; - } - if (next_offset) - server->pdu_size = next_offset; + if (smb2_next_header(server, buf, &next_offset)) { + cifs_dbg(VFS, "%s: malformed response (next_offset=%u)\n", + __func__, next_offset); + cifs_reconnect(server, true); + continue; } + if (next_offset) + server->pdu_size = next_offset; memset(mids, 0, sizeof(mids)); memset(bufs, 0, sizeof(bufs)); @@ -1243,7 +1236,7 @@ next_pdu: bufs, &num_mids); } else { - mids[0] = server->ops->find_mid(server, buf); + mids[0] = smb2_find_mid(server, buf); bufs[0] = buf; num_mids = 1; @@ -1260,8 +1253,7 @@ next_pdu: continue; } - if (server->ops->is_status_io_timeout && - server->ops->is_status_io_timeout(buf)) { + if (smb2_is_status_io_timeout(buf)) { num_io_timeout++; if (num_io_timeout > MAX_STATUS_IO_TIMEOUT) { cifs_server_dbg(VFS, @@ -1280,11 +1272,8 @@ next_pdu: mids[i]->resp_buf_size = server->pdu_size; if (bufs[i] != NULL) { - if (server->ops->is_network_name_deleted && - server->ops->is_network_name_deleted(bufs[i], - server)) { - cifs_server_dbg(FYI, - "Share deleted. Reconnect needed"); + if (smb2_is_network_name_deleted(bufs[i], server)) { + cifs_server_dbg(FYI, "Share deleted. Reconnect needed"); } } @@ -1292,9 +1281,7 @@ next_pdu: mids[i]->callback(mids[i]); release_mid(mids[i]); - } else if (server->ops->is_oplock_break && - server->ops->is_oplock_break(bufs[i], - server)) { + } else if (smb2_is_valid_oplock_break(bufs[i], server)) { smb2_add_credits_from_hdr(bufs[i], server); cifs_dbg(FYI, "Received oplock break\n"); } else { @@ -1304,9 +1291,7 @@ next_pdu: HEADER_SIZE(server)); smb2_add_credits_from_hdr(bufs[i], server); #ifdef CONFIG_CIFS_DEBUG2 - if (server->ops->dump_detail) - server->ops->dump_detail(bufs[i], - server); + smb2_dump_detail(bufs[i], server); cifs_dump_mids(server); #endif /* CIFS_DEBUG2 */ } @@ -1484,8 +1469,7 @@ match_security(struct TCP_Server_Info *server, struct smb3_fs_context *ctx) * that was specified, or "Unspecified" if that sectype was not * compatible with the given NEGOTIATE request. */ - if (server->ops->select_sectype(server, ctx->sectype) - == Unspecified) + if (smb2_select_sectype(server, ctx->sectype) == Unspecified) return false; /* @@ -1951,7 +1935,7 @@ cifs_setup_ipc(struct cifs_ses *ses, struct smb3_fs_context *ctx) tcon->ses = ses; tcon->ipc = true; tcon->seal = seal; - rc = server->ops->tree_connect(xid, ses, unc, tcon, ctx->local_nls); + rc = SMB2_tcon(xid, ses, unc, tcon, ctx->local_nls); free_xid(xid); if (rc) { @@ -2024,7 +2008,7 @@ void __cifs_put_smb_ses(struct cifs_ses *ses) cifs_chan_clear_need_reconnect(ses, server); spin_unlock(&ses->chan_lock); - do_logoff = ses->ses_status == SES_GOOD && server->ops->logoff; + do_logoff = ses->ses_status == SES_GOOD && SMB2_logoff; ses->ses_status = SES_EXITING; tcon = ses->tcon_ipc; ses->tcon_ipc = NULL; @@ -2042,7 +2026,7 @@ void __cifs_put_smb_ses(struct cifs_ses *ses) tconInfoFree(tcon, netfs_trace_tcon_ref_free_ipc); if (do_logoff) { xid = get_xid(); - rc = server->ops->logoff(xid, ses); + rc = SMB2_logoff(xid, ses); if (rc) cifs_server_dbg(VFS, "%s: Session Logoff failure rc=%d\n", __func__, rc); @@ -2487,8 +2471,7 @@ cifs_put_tcon(struct cifs_tcon *tcon, enum smb3_tcon_ref_trace trace) } xid = get_xid(); - if (ses->server->ops->tree_disconnect) - ses->server->ops->tree_disconnect(xid, tcon); + SMB2_tdis(xid, tcon); _free_xid(xid); cifs_fscache_release_super_cookie(tcon); @@ -2536,11 +2519,6 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx) return tcon; } - if (!ses->server->ops->tree_connect) { - rc = -ENOSYS; - goto out_fail; - } - if (ses->server->capabilities & SMB2_GLOBAL_CAP_DIRECTORY_LEASING) nohandlecache = ctx->nohandlecache; else @@ -2618,8 +2596,7 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx) } xid = get_xid(); - rc = ses->server->ops->tree_connect(xid, ses, ctx->UNC, tcon, - ctx->local_nls); + rc = SMB2_tcon(xid, ses, ctx->UNC, tcon, ctx->local_nls); free_xid(xid); cifs_dbg(FYI, "Tcon rc = %d\n", rc); if (rc) @@ -3392,7 +3369,7 @@ cifs_are_all_path_components_accessible(struct TCP_Server_Info *server, sep = CIFS_DIR_SEP(cifs_sb); s = full_path; - rc = server->ops->is_path_accessible(xid, tcon, cifs_sb, ""); + rc = smb2_is_path_accessible(xid, tcon, cifs_sb, ""); while (rc == 0) { /* skip separators */ while (*s == sep) @@ -3416,7 +3393,7 @@ cifs_are_all_path_components_accessible(struct TCP_Server_Info *server, */ tmp = *s; *s = 0; - rc = server->ops->is_path_accessible(xid, tcon, cifs_sb, + rc = smb2_is_path_accessible(xid, tcon, cifs_sb, full_path); *s = tmp; } @@ -3438,9 +3415,6 @@ int cifs_is_path_remote(struct cifs_mount_ctx *mnt_ctx) struct smb3_fs_context *ctx = mnt_ctx->fs_ctx; char *full_path; - if (!server->ops->is_path_accessible) - return -EOPNOTSUPP; - /* * cifs_build_path_to_root works only when we have a valid tcon */ @@ -3450,7 +3424,7 @@ int cifs_is_path_remote(struct cifs_mount_ctx *mnt_ctx) cifs_dbg(FYI, "%s: full_path: %s\n", __func__, full_path); - rc = server->ops->is_path_accessible(xid, tcon, cifs_sb, + rc = smb2_is_path_accessible(xid, tcon, cifs_sb, full_path); if (rc != 0 && rc != -EREMOTE) goto out; @@ -3597,9 +3571,6 @@ cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses, { int rc = 0; - if (!server->ops->need_neg || !server->ops->negotiate) - return -ENOSYS; - /* only send once per connect */ spin_lock(&server->srv_lock); if (server->tcpStatus != CifsGood && @@ -3609,8 +3580,7 @@ cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses, return -EHOSTDOWN; } - if (!server->ops->need_neg(server) && - server->tcpStatus == CifsGood) { + if (!smb2_need_neg(server) && server->tcpStatus == CifsGood) { spin_unlock(&server->srv_lock); return 0; } @@ -3618,7 +3588,7 @@ cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses, server->tcpStatus = CifsInNegotiate; spin_unlock(&server->srv_lock); - rc = server->ops->negotiate(xid, ses, server); + rc = smb2_negotiate(xid, ses, server); if (rc == 0) { spin_lock(&server->srv_lock); if (server->tcpStatus == CifsInNegotiate) @@ -3705,8 +3675,7 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses, cifs_dbg(FYI, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d\n", server->sec_mode, server->capabilities, server->timeAdj); - if (server->ops->sess_setup) - rc = server->ops->sess_setup(xid, ses, server, nls_info); + rc = SMB2_sess_setup(xid, ses, server, nls_info); if (rc) { cifs_server_dbg(VFS, "Send error in SessSetup = %d\n", rc); @@ -4039,7 +4008,6 @@ cifs_prune_tlinks(struct work_struct *work) int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const struct nls_table *nlsc) { int rc; - const struct smb_version_operations *ops = tcon->ses->server->ops; /* only send once per connect */ spin_lock(&tcon->tc_lock); @@ -4062,7 +4030,7 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru tcon->status = TID_IN_TCON; spin_unlock(&tcon->tc_lock); - rc = ops->tree_connect(xid, tcon->ses, tcon->tree_name, tcon, nlsc); + rc = SMB2_tcon(xid, tcon->ses, tcon->tree_name, tcon, nlsc); if (rc) { spin_lock(&tcon->tc_lock); if (tcon->status == TID_IN_TCON) diff --git a/fs/smb/client/dfs.c b/fs/smb/client/dfs.c index 3ec965547e3d..4c9d5e0441bf 100644 --- a/fs/smb/client/dfs.c +++ b/fs/smb/client/dfs.c @@ -416,8 +416,7 @@ static void __tree_connect_ipc(const unsigned int xid, char *tree, scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$", server->hostname); cifs_server_unlock(server); - rc = server->ops->tree_connect(xid, ses, tree, tcon, - cifs_sb->local_nls); + rc = SMB2_tcon(xid, ses, tree, tcon, cifs_sb->local_nls); cifs_server_dbg(FYI, "%s: tree_reconnect %s: %d\n", __func__, tree, rc); spin_lock(&tcon->tc_lock); if (rc) { @@ -445,7 +444,6 @@ static int __tree_connect_dfs_target(const unsigned int xid, struct cifs_tcon *t { int rc; struct TCP_Server_Info *server = tcon->ses->server; - const struct smb_version_operations *ops = server->ops; struct cifs_ses *root_ses = CIFS_DFS_ROOT_SES(tcon->ses); char *share = NULL, *prefix = NULL; struct dfs_cache_tgt_iterator *tit; @@ -486,7 +484,7 @@ static int __tree_connect_dfs_target(const unsigned int xid, struct cifs_tcon *t scnprintf(tree, MAX_TREE_SIZE, "\\%s", share); if (!islink) { - rc = ops->tree_connect(xid, tcon->ses, tree, tcon, cifs_sb->local_nls); + rc = SMB2_tcon(xid, tcon->ses, tree, tcon, cifs_sb->local_nls); break; } @@ -498,7 +496,7 @@ static int __tree_connect_dfs_target(const unsigned int xid, struct cifs_tcon *t */ if (dfs_cache_find(xid, root_ses, cifs_sb->local_nls, cifs_remap(cifs_sb), target, NULL, &ntl)) { - rc = ops->tree_connect(xid, tcon->ses, tree, tcon, cifs_sb->local_nls); + rc = SMB2_tcon(xid, tcon->ses, tree, tcon, cifs_sb->local_nls); if (rc) continue; @@ -553,7 +551,6 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru { int rc; struct TCP_Server_Info *server = tcon->ses->server; - const struct smb_version_operations *ops = server->ops; DFS_CACHE_TGT_LIST(tl); struct cifs_sb_info *cifs_sb = NULL; struct super_block *sb = NULL; @@ -591,7 +588,7 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru cifs_server_lock(server); scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$", server->hostname); cifs_server_unlock(server); - rc = ops->tree_connect(xid, tcon->ses, tree, tcon, nlsc); + rc = SMB2_tcon(xid, tcon->ses, tree, tcon, nlsc); goto out; } @@ -605,8 +602,8 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru */ if (!cifs_sb || !server->leaf_fullpath || dfs_cache_noreq_find(server->leaf_fullpath + 1, &ref, &tl)) { - rc = ops->tree_connect(xid, tcon->ses, tcon->tree_name, tcon, - cifs_sb ? cifs_sb->local_nls : nlsc); + rc = SMB2_tcon(xid, tcon->ses, tcon->tree_name, tcon, + cifs_sb ? cifs_sb->local_nls : nlsc); goto out; } diff --git a/fs/smb/client/dfs_cache.c b/fs/smb/client/dfs_cache.c index 11c8efecf7aa..d197be8979b8 100644 --- a/fs/smb/client/dfs_cache.c +++ b/fs/smb/client/dfs_cache.c @@ -652,13 +652,13 @@ static int get_dfs_referral(const unsigned int xid, struct cifs_ses *ses, const *refs = NULL; *numrefs = 0; - if (!ses || !ses->server || !ses->server->ops->get_dfs_refer) + if (!ses || !ses->server) return -EOPNOTSUPP; if (unlikely(!cache_cp)) return -EINVAL; cifs_dbg(FYI, "%s: ipc=%s referral=%s\n", __func__, ses->tcon_ipc->tree_name, path); - rc = ses->server->ops->get_dfs_refer(xid, ses, path, refs, numrefs, cache_cp, + rc = smb2_get_dfs_refer(xid, ses, path, refs, numrefs, cache_cp, NO_MAP_UNI_RSVD); if (!rc) { struct dfs_info3_param *ref = *refs; diff --git a/fs/smb/client/dir.c b/fs/smb/client/dir.c index 66248c1e78da..01bb87eaf1f2 100644 --- a/fs/smb/client/dir.c +++ b/fs/smb/client/dir.c @@ -228,11 +228,6 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned * ACLs */ - if (!server->ops->open) { - rc = -ENOSYS; - goto out; - } - /* * if we're not using unix extensions, see if we need to set * ATTR_READONLY on the create call @@ -251,7 +246,7 @@ retry_open: .fid = fid, .mode = mode, }; - rc = server->ops->open(xid, &oparms, oplock, buf); + rc = smb2_open_file(xid, &oparms, oplock, buf); if (rc) { cifs_dbg(FYI, "cifs_create returned 0x%x\n", rc); if (rc == -EACCES && rdwr_for_fscache == 1) { @@ -268,8 +263,7 @@ retry_open: /* TODO: Add support for calling POSIX query info here, but passing in fid */ rc = cifs_get_inode_info(&newinode, full_path, buf, inode->i_sb, xid, fid); if (newinode) { - if (server->ops->set_lease_key) - server->ops->set_lease_key(newinode, fid); + smb2_set_lease_key(newinode, fid); if ((*oplock & CIFS_CREATE_ACTION) && S_ISREG(newinode->i_mode)) { if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) newinode->i_mode = mode; @@ -304,8 +298,7 @@ out: return rc; out_err: - if (server->ops->close) - server->ops->close(xid, tcon, fid); + smb2_close_file(xid, tcon, fid); if (newinode) iput(newinode); goto out; @@ -376,9 +369,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, server = tcon->ses->server; - if (server->ops->new_lease_key) - server->ops->new_lease_key(&fid); - + smb2_new_lease_key(&fid); cifs_add_pending_open(&fid, tlink, &open); rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, @@ -393,8 +384,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, rc = finish_open(file, direntry, generic_file_open); if (rc) { - if (server->ops->close) - server->ops->close(xid, tcon, &fid); + smb2_close_file(xid, tcon, &fid); cifs_del_pending_open(&open); goto out; } @@ -409,8 +399,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, file_info = cifs_new_fileinfo(&fid, file, tlink, oplock, buf.symlink_target); if (file_info == NULL) { - if (server->ops->close) - server->ops->close(xid, tcon, &fid); + smb2_close_file(xid, tcon, &fid); cifs_del_pending_open(&open); rc = -ENOMEM; goto out; @@ -463,12 +452,11 @@ int cifs_create(struct mnt_idmap *idmap, struct inode *inode, tcon = tlink_tcon(tlink); server = tcon->ses->server; - if (server->ops->new_lease_key) - server->ops->new_lease_key(&fid); + smb2_new_lease_key(&fid); rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, &oplock, &fid, &buf); - if (!rc && server->ops->close) - server->ops->close(xid, tcon, &fid); + if (!rc) + smb2_close_file(xid, tcon, &fid); cifs_free_open_info(&buf); cifs_put_tlink(tlink); @@ -511,7 +499,7 @@ int cifs_mknod(struct mnt_idmap *idmap, struct inode *inode, trace_smb3_mknod_enter(xid, tcon->ses->Suid, tcon->tid, full_path); - rc = tcon->ses->server->ops->make_node(xid, inode, direntry, tcon, + rc = smb2_make_node(xid, inode, direntry, tcon, full_path, mode, device_number); diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c index 1ff1fce50198..30b3abcfc904 100644 --- a/fs/smb/client/file.c +++ b/fs/smb/client/file.c @@ -73,7 +73,7 @@ retry: } } - rc = server->ops->wait_mtu_credits(server, wsize, &wdata->subreq.max_len, + rc = smb2_wait_mtu_credits(server, wsize, &wdata->subreq.max_len, &wdata->credits); if (rc < 0) { subreq->error = rc; @@ -120,7 +120,7 @@ static void cifs_issue_write(struct netfs_io_subrequest *subreq) if (wdata->req->cfile->invalidHandle) goto fail; - wdata->server->ops->async_writev(wdata); + smb2_async_writev(wdata); out: return; @@ -167,7 +167,7 @@ static bool cifs_clamp_length(struct netfs_io_subrequest *subreq) cifs_sb->ctx); - rc = server->ops->wait_mtu_credits(server, cifs_sb->ctx->rsize, + rc = smb2_wait_mtu_credits(server, cifs_sb->ctx->rsize, &rsize, &rdata->credits); if (rc) { subreq->error = rc; @@ -224,7 +224,7 @@ static void cifs_req_issue_read(struct netfs_io_subrequest *subreq) size_t rsize = umin(subreq->len - subreq->transferred, cifs_sb->ctx->rsize); - rc = server->ops->wait_mtu_credits(server, rsize, &rdata->actual_len, + rc = smb2_wait_mtu_credits(server, rsize, &rdata->actual_len, &rdata->credits); if (rc) goto out; @@ -249,7 +249,7 @@ static void cifs_req_issue_read(struct netfs_io_subrequest *subreq) if (subreq->rreq->origin != NETFS_DIO_READ) __set_bit(NETFS_SREQ_CLEAR_TAIL, &subreq->flags); - rc = rdata->server->ops->async_readv(rdata); + rc = smb2_async_readv(rdata); out: if (rc) netfs_subreq_terminated(subreq, rc, false); @@ -469,9 +469,6 @@ static int cifs_nt_open(const char *full_path, struct inode *inode, struct cifs_ struct cifs_open_parms oparms; int rdwr_for_fscache = 0; - if (!server->ops->open) - return -ENOSYS; - /* If we're caching, we need to be able to fill in around partial writes. */ if (cifs_fscache_enabled(inode) && (f_flags & O_ACCMODE) == O_WRONLY) rdwr_for_fscache = 1; @@ -524,7 +521,7 @@ retry_open: .fid = fid, }; - rc = server->ops->open(xid, &oparms, oplock, buf); + rc = smb2_open_file(xid, &oparms, oplock, buf); if (rc) { if (rc == -EACCES && rdwr_for_fscache == 1) { desired_access = cifs_convert_flags(f_flags, 0); @@ -545,7 +542,7 @@ retry_open: xid, fid); if (rc) { - server->ops->close(xid, tcon, fid); + smb2_close_file(xid, tcon, fid); if (rc == -ESTALE) rc = -EOPENSTALE; } @@ -651,7 +648,7 @@ struct cifsFileInfo *cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, list_del(&fid->pending_open->olist); fid->purge_cache = false; - server->ops->set_fid(cfile, fid, oplock); + smb2_set_fid(cfile, fid, oplock); list_add(&cfile->tlist, &tcon->openFileList); atomic_inc(&tcon->num_local_opens); @@ -732,8 +729,8 @@ void serverclose_work(struct work_struct *work) do { if (server->ops->close_getattr) rc = server->ops->close_getattr(0, tcon, cifs_file); - else if (server->ops->close) - rc = server->ops->close(0, tcon, &cifs_file->fid); + else + rc = smb2_close_file(0, tcon, &cifs_file->fid); if (rc == -EBUSY || rc == -EAGAIN) { retries++; @@ -806,8 +803,7 @@ void _cifsFileInfo_put(struct cifsFileInfo *cifs_file, } spin_unlock(&cifs_file->file_info_lock); - if (server->ops->get_lease_key) - server->ops->get_lease_key(inode, &fid); + smb2_get_lease_key(inode, &fid); /* store open in pending opens to make sure we don't miss lease break */ cifs_add_pending_open_locked(&fid, cifs_file->tlink, &open); @@ -844,8 +840,8 @@ void _cifsFileInfo_put(struct cifsFileInfo *cifs_file, xid = get_xid(); if (server->ops->close_getattr) rc = server->ops->close_getattr(xid, tcon, cifs_file); - else if (server->ops->close) - rc = server->ops->close(xid, tcon, &cifs_file->fid); + else + rc = smb2_close_file(xid, tcon, &cifs_file->fid); _free_xid(xid); if (rc == -EBUSY || rc == -EAGAIN) { @@ -943,14 +939,11 @@ int cifs_open(struct inode *inode, struct file *file) oplock = 0; - if (server->ops->get_lease_key) - server->ops->get_lease_key(inode, &fid); - + smb2_get_lease_key(inode, &fid); cifs_add_pending_open(&fid, tlink, &open); if (!posix_open_ok) { - if (server->ops->get_lease_key) - server->ops->get_lease_key(inode, &fid); + smb2_get_lease_key(inode, &fid); rc = cifs_nt_open(full_path, inode, cifs_sb, tcon, file->f_flags, &oplock, &fid, xid, &data); @@ -962,8 +955,7 @@ int cifs_open(struct inode *inode, struct file *file) cfile = cifs_new_fileinfo(&fid, file, tlink, oplock, data.symlink_target); if (cfile == NULL) { - if (server->ops->close) - server->ops->close(xid, tcon, &fid); + smb2_close_file(xid, tcon, &fid); cifs_del_pending_open(&open); rc = -ENOMEM; goto out; @@ -1006,7 +998,7 @@ cifs_relock_file(struct cifsFileInfo *cfile) return rc; } - rc = tcon->ses->server->ops->push_mand_locks(cfile); + rc = smb2_push_mandatory_locks(cfile); up_read(&cinode->lock_sem); return rc; @@ -1081,9 +1073,7 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush) if (cfile->f_flags & O_DIRECT) create_options |= CREATE_NO_BUFFER; - if (server->ops->get_lease_key) - server->ops->get_lease_key(inode, &cfile->fid); - + smb2_get_lease_key(inode, &cfile->fid); retry_open: oparms = (struct cifs_open_parms) { .tcon = tcon, @@ -1103,10 +1093,10 @@ retry_open: * version of file size can be stale. If we knew for sure that inode was * not dirty locally we could do this. */ - rc = server->ops->open(xid, &oparms, &oplock, NULL); + rc = smb2_open_file(xid, &oparms, &oplock, NULL); if (rc == -ENOENT && oparms.reconnect == false) { /* durable handle timeout is expired - open the file again */ - rc = server->ops->open(xid, &oparms, &oplock, NULL); + rc = smb2_open_file(xid, &oparms, &oplock, NULL); /* indicate that we need to relock the file */ oparms.reconnect = true; } @@ -1162,7 +1152,7 @@ retry_open: oplock = 0; } - server->ops->set_fid(cfile, &cfile->fid, oplock); + smb2_set_fid(cfile, &cfile->fid, oplock); if (oparms.reconnect) cifs_relock_file(cfile); @@ -1299,13 +1289,10 @@ int cifs_closedir(struct inode *inode, struct file *file) cifs_dbg(FYI, "Freeing private data in close dir\n"); spin_lock(&cfile->file_info_lock); - if (server->ops->dir_needs_close(cfile)) { + if (smb2_dir_needs_close(cfile)) { cfile->invalidHandle = true; spin_unlock(&cfile->file_info_lock); - if (server->ops->close_dir) - rc = server->ops->close_dir(xid, tcon, &cfile->fid); - else - rc = -ENOSYS; + rc = smb2_close_dir(xid, tcon, &cfile->fid); cifs_dbg(FYI, "Closing uncompleted readdir with rc %d\n", rc); /* not much we can do if it fails anyway, ignore rc */ rc = 0; @@ -1377,19 +1364,19 @@ cifs_find_fid_lock_conflict(struct cifs_fid_locks *fdlocks, __u64 offset, offset >= li->offset + li->length) continue; if (rw_check != CIFS_LOCK_OP && current->tgid == li->pid && - server->ops->compare_fids(cfile, cur_cfile)) { + smb2_compare_fids(cfile, cur_cfile)) { /* shared lock prevents write op through the same fid */ if (!(li->type & server->vals->shared_lock_type) || rw_check != CIFS_WRITE_OP) continue; } if ((type & server->vals->shared_lock_type) && - ((server->ops->compare_fids(cfile, cur_cfile) && + ((smb2_compare_fids(cfile, cur_cfile) && current->tgid == li->pid) || type == li->type)) continue; if (rw_check == CIFS_LOCK_OP && (flags & FL_OFDLCK) && (li->flags & FL_OFDLCK) && - server->ops->compare_fids(cfile, cur_cfile)) + smb2_compare_fids(cfile, cur_cfile)) continue; if (conf_lock) *conf_lock = li; @@ -1539,7 +1526,7 @@ cifs_push_locks(struct cifsFileInfo *cfile) return rc; } - rc = tcon->ses->server->ops->push_mand_locks(cfile); + rc = smb2_push_mandatory_locks(cfile); cinode->can_cache_brlcks = false; up_write(&cinode->lock_sem); @@ -1609,10 +1596,10 @@ cifs_getlk(struct file *file, struct file_lock *flock, __u32 type, return rc; /* BB we could chain these into one lock request BB */ - rc = server->ops->mand_lock(xid, cfile, flock->fl_start, length, type, + rc = smb2_mand_lock(xid, cfile, flock->fl_start, length, type, 1, 0, false); if (rc == 0) { - rc = server->ops->mand_lock(xid, cfile, flock->fl_start, length, + rc = smb2_mand_lock(xid, cfile, flock->fl_start, length, type, 0, 1, false); flock->c.flc_type = F_UNLCK; if (rc != 0) @@ -1628,11 +1615,11 @@ cifs_getlk(struct file *file, struct file_lock *flock, __u32 type, type &= ~server->vals->exclusive_lock_type; - rc = server->ops->mand_lock(xid, cfile, flock->fl_start, length, + rc = smb2_mand_lock(xid, cfile, flock->fl_start, length, type | server->vals->shared_lock_type, 1, 0, false); if (rc == 0) { - rc = server->ops->mand_lock(xid, cfile, flock->fl_start, length, + rc = smb2_mand_lock(xid, cfile, flock->fl_start, length, type | server->vals->shared_lock_type, 0, 1, false); flock->c.flc_type = F_RDLCK; if (rc != 0) @@ -1707,7 +1694,7 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type, CIFS_I(inode)->oplock = 0; } - rc = server->ops->mand_lock(xid, cfile, flock->fl_start, length, + rc = smb2_mand_lock(xid, cfile, flock->fl_start, length, type, 1, 0, wait_flag); if (rc) { kfree(lock); @@ -1716,7 +1703,7 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type, cifs_lock_add(cfile, lock); } else if (unlock) - rc = server->ops->mand_unlock_range(cfile, flock, xid); + rc = smb2_unlock_range(cfile, flock, xid); out: if ((flock->c.flc_flags & FL_POSIX) || (flock->c.flc_flags & FL_FLOCK)) { @@ -2102,20 +2089,16 @@ int cifs_strict_fsync(struct file *file, loff_t start, loff_t end, tcon = tlink_tcon(smbfile->tlink); if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) { server = tcon->ses->server; - if (server->ops->flush == NULL) { - rc = -ENOSYS; - goto strict_fsync_exit; - } if ((OPEN_FMODE(smbfile->f_flags) & FMODE_WRITE) == 0) { smbfile = find_writable_file(CIFS_I(inode), FIND_WR_ANY); if (smbfile) { - rc = server->ops->flush(xid, tcon, &smbfile->fid); + rc = smb2_flush_file(xid, tcon, &smbfile->fid); cifsFileInfo_put(smbfile); } else cifs_dbg(FYI, "ignore fsync for file not open for write\n"); } else - rc = server->ops->flush(xid, tcon, &smbfile->fid); + rc = smb2_flush_file(xid, tcon, &smbfile->fid); } strict_fsync_exit: @@ -2150,20 +2133,16 @@ int cifs_fsync(struct file *file, loff_t start, loff_t end, int datasync) tcon = tlink_tcon(smbfile->tlink); if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) { server = tcon->ses->server; - if (server->ops->flush == NULL) { - rc = -ENOSYS; - goto fsync_exit; - } if ((OPEN_FMODE(smbfile->f_flags) & FMODE_WRITE) == 0) { smbfile = find_writable_file(CIFS_I(inode), FIND_WR_ANY); if (smbfile) { - rc = server->ops->flush(xid, tcon, &smbfile->fid); + rc = smb2_flush_file(xid, tcon, &smbfile->fid); cifsFileInfo_put(smbfile); } else cifs_dbg(FYI, "ignore fsync for file not open for wri