diff options
Diffstat (limited to 'fs/smb')
| -rw-r--r-- | fs/smb/client/cifsglob.h | 6 | ||||
| -rw-r--r-- | fs/smb/client/connect.c | 4 | ||||
| -rw-r--r-- | fs/smb/client/file.c | 1 | ||||
| -rw-r--r-- | fs/smb/client/inode.c | 21 | ||||
| -rw-r--r-- | fs/smb/client/smb1transport.c | 2 | ||||
| -rw-r--r-- | fs/smb/client/smb2ops.c | 20 | ||||
| -rw-r--r-- | fs/smb/server/mgmt/tree_connect.c | 9 | ||||
| -rw-r--r-- | fs/smb/server/smb2pdu.c | 17 |
8 files changed, 39 insertions, 41 deletions
diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index 7877d327dbb0..709e96e07791 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -2386,4 +2386,10 @@ static inline int cifs_open_create_options(unsigned int oflags, int opts) return opts; } +/* + * The number of blocks is not related to (i_size / i_blksize), but instead + * 512 byte (2**9) size is required for calculating num blocks. + */ +#define CIFS_INO_BLOCKS(size) DIV_ROUND_UP_ULL((u64)(size), 512) + #endif /* _CIFS_GLOB_H */ diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c index 3bad2c5c523d..69b38f0ccf2b 100644 --- a/fs/smb/client/connect.c +++ b/fs/smb/client/connect.c @@ -1955,6 +1955,10 @@ static int match_session(struct cifs_ses *ses, case Kerberos: if (!uid_eq(ctx->cred_uid, ses->cred_uid)) return 0; + if (strncmp(ses->user_name ?: "", + ctx->username ?: "", + CIFS_MAX_USERNAME_LEN)) + return 0; break; case NTLMv2: case RawNTLMSSP: diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c index 27f61fe7e4e2..a69e05f86d7e 100644 --- a/fs/smb/client/file.c +++ b/fs/smb/client/file.c @@ -993,7 +993,6 @@ static int cifs_do_truncate(const unsigned int xid, struct dentry *dentry) if (!rc) { netfs_resize_file(&cinode->netfs, 0, true); cifs_setsize(inode, 0); - inode->i_blocks = 0; } } if (cfile) diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c index 143fa2e665ed..888f9e35f14b 100644 --- a/fs/smb/client/inode.c +++ b/fs/smb/client/inode.c @@ -219,13 +219,7 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr, */ if (is_size_safe_to_change(cifs_i, fattr->cf_eof, from_readdir)) { i_size_write(inode, fattr->cf_eof); - - /* - * i_blocks is not related to (i_size / i_blksize), - * but instead 512 byte (2**9) size is required for - * calculating num blocks. - */ - inode->i_blocks = (512 - 1 + fattr->cf_bytes) >> 9; + inode->i_blocks = CIFS_INO_BLOCKS(fattr->cf_bytes); } if (S_ISLNK(fattr->cf_mode) && fattr->cf_symlink_target) { @@ -3015,6 +3009,11 @@ void cifs_setsize(struct inode *inode, loff_t offset) { spin_lock(&inode->i_lock); i_size_write(inode, offset); + /* + * Until we can query the server for actual allocation size, + * this is best estimate we have for blocks allocated for a file. + */ + inode->i_blocks = CIFS_INO_BLOCKS(offset); spin_unlock(&inode->i_lock); inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); truncate_pagecache(inode, offset); @@ -3087,14 +3086,6 @@ set_size_out: if (rc == 0) { netfs_resize_file(&cifsInode->netfs, size, true); cifs_setsize(inode, size); - /* - * i_blocks is not related to (i_size / i_blksize), but instead - * 512 byte (2**9) size is required for calculating num blocks. - * Until we can query the server for actual allocation size, - * this is best estimate we have for blocks allocated for a file - * Number of blocks must be rounded up so size 1 is not 0 blocks - */ - inode->i_blocks = (512 - 1 + size) >> 9; } return rc; diff --git a/fs/smb/client/smb1transport.c b/fs/smb/client/smb1transport.c index 38d6d5538b96..53abb29fe71b 100644 --- a/fs/smb/client/smb1transport.c +++ b/fs/smb/client/smb1transport.c @@ -460,7 +460,7 @@ check_smb_hdr(struct smb_hdr *smb) return 0; /* - * Windows NT server returns error resposne (e.g. STATUS_DELETE_PENDING + * Windows NT server returns error response (e.g. STATUS_DELETE_PENDING * or STATUS_OBJECT_NAME_NOT_FOUND or ERRDOS/ERRbadfile or any other) * for some TRANS2 requests without the RESPONSE flag set in header. */ diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index 98ac4e86bf99..509fcea28a42 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -1497,6 +1497,7 @@ smb2_close_getattr(const unsigned int xid, struct cifs_tcon *tcon, { struct smb2_file_network_open_info file_inf; struct inode *inode; + u64 asize; int rc; rc = __SMB2_close(xid, tcon, cfile->fid.persistent_fid, @@ -1520,14 +1521,9 @@ smb2_close_getattr(const unsigned int xid, struct cifs_tcon *tcon, inode_set_atime_to_ts(inode, cifs_NTtimeToUnix(file_inf.LastAccessTime)); - /* - * i_blocks is not related to (i_size / i_blksize), - * but instead 512 byte (2**9) size is required for - * calculating num blocks. - */ - if (le64_to_cpu(file_inf.AllocationSize) > 4096) - inode->i_blocks = - (512 - 1 + le64_to_cpu(file_inf.AllocationSize)) >> 9; + asize = le64_to_cpu(file_inf.AllocationSize); + if (asize > 4096) + inode->i_blocks = CIFS_INO_BLOCKS(asize); /* End of file and Attributes should not have to be updated on close */ spin_unlock(&inode->i_lock); @@ -2204,14 +2200,6 @@ smb2_duplicate_extents(const unsigned int xid, rc = smb2_set_file_size(xid, tcon, trgtfile, dest_off + len, false); if (rc) goto duplicate_extents_out; - - /* - * Although also could set plausible allocation size (i_blocks) - * here in addition to setting the file size, in reflink - * it is likely that the target file is sparse. Its allocation - * size will be queried on next revalidate, but it is important - * to make sure that file's cached size is updated immediately - */ netfs_resize_file(netfs_inode(inode), dest_off + len, true); cifs_setsize(inode, dest_off + len); } diff --git a/fs/smb/server/mgmt/tree_connect.c b/fs/smb/server/mgmt/tree_connect.c index a72d7e42a6c2..58e5b8592da4 100644 --- a/fs/smb/server/mgmt/tree_connect.c +++ b/fs/smb/server/mgmt/tree_connect.c @@ -102,8 +102,10 @@ out_error: void ksmbd_tree_connect_put(struct ksmbd_tree_connect *tcon) { - if (atomic_dec_and_test(&tcon->refcount)) + if (atomic_dec_and_test(&tcon->refcount)) { + ksmbd_share_config_put(tcon->share_conf); kfree(tcon); + } } static int __ksmbd_tree_conn_disconnect(struct ksmbd_session *sess, @@ -113,10 +115,11 @@ static int __ksmbd_tree_conn_disconnect(struct ksmbd_session *sess, ret = ksmbd_ipc_tree_disconnect_request(sess->id, tree_conn->id); ksmbd_release_tree_conn_id(sess, tree_conn->id); - ksmbd_share_config_put(tree_conn->share_conf); ksmbd_counter_dec(KSMBD_COUNTER_TREE_CONNS); - if (atomic_dec_and_test(&tree_conn->refcount)) + if (atomic_dec_and_test(&tree_conn->refcount)) { + ksmbd_share_config_put(tree_conn->share_conf); kfree(tree_conn); + } return ret; } diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 9f7ff7491e9a..9c44e71e3c3b 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -126,6 +126,8 @@ int smb2_get_ksmbd_tcon(struct ksmbd_work *work) pr_err("The first operation in the compound does not have tcon\n"); return -EINVAL; } + if (work->tcon->t_state != TREE_CONNECTED) + return -ENOENT; if (tree_id != UINT_MAX && work->tcon->id != tree_id) { pr_err("tree id(%u) is different with id(%u) in first operation\n", tree_id, work->tcon->id); @@ -1948,6 +1950,7 @@ out_err: } } smb2_set_err_rsp(work); + conn->binding = false; } else { unsigned int iov_len; @@ -2828,7 +2831,11 @@ static int parse_durable_handle_context(struct ksmbd_work *work, goto out; } - dh_info->fp->conn = conn; + if (dh_info->fp->conn) { + ksmbd_put_durable_fd(dh_info->fp); + err = -EBADF; + goto out; + } dh_info->reconnected = true; goto out; } @@ -5452,7 +5459,6 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, struct smb2_query_info_req *req, struct smb2_query_info_rsp *rsp) { - struct ksmbd_session *sess = work->sess; struct ksmbd_conn *conn = work->conn; struct ksmbd_share_config *share = work->tcon->share_conf; int fsinfoclass = 0; @@ -5589,10 +5595,11 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, info = (struct object_id_info *)(rsp->Buffer); - if (!user_guest(sess->user)) - memcpy(info->objid, user_passkey(sess->user), 16); + if (path.mnt->mnt_sb->s_uuid_len == 16) + memcpy(info->objid, path.mnt->mnt_sb->s_uuid.b, + path.mnt->mnt_sb->s_uuid_len); else - memset(info->objid, 0, 16); + memcpy(info->objid, &stfs.f_fsid, sizeof(stfs.f_fsid)); info->extended_info.magic = cpu_to_le32(EXTENDED_INFO_MAGIC); info->extended_info.version = cpu_to_le32(1); |
