Loading fs/ksmbd/smb2pdu.c +45 −37 Original line number Diff line number Diff line Loading @@ -2768,8 +2768,13 @@ int smb2_open(struct ksmbd_work *work) if (!file_present) { rc = smb2_creat(work, &path, name, open_flags, posix_mode, req->CreateOptions & FILE_DIRECTORY_FILE_LE); if (rc) if (rc) { if (rc == -ENOENT) { rc = -EIO; rsp->hdr.Status = STATUS_OBJECT_PATH_NOT_FOUND; } goto err_out; } created = true; user_ns = mnt_user_ns(path.mnt); Loading Loading @@ -6582,7 +6587,7 @@ int smb2_lock(struct ksmbd_work *work) int lock_count; int flags = 0; int cmd = 0; int err = 0, i; int err = -EIO, i, rc = 0; u64 lock_start, lock_length; struct ksmbd_lock *smb_lock = NULL, *cmp_lock, *tmp, *tmp2; struct ksmbd_conn *conn; Loading @@ -6598,7 +6603,7 @@ int smb2_lock(struct ksmbd_work *work) if (!fp) { ksmbd_debug(SMB, "Invalid file id for lock : %llu\n", le64_to_cpu(req->VolatileFileId)); rsp->hdr.Status = STATUS_FILE_CLOSED; err = -ENOENT; goto out2; } Loading @@ -6608,7 +6613,7 @@ int smb2_lock(struct ksmbd_work *work) ksmbd_debug(SMB, "lock count is %d\n", lock_count); if (!lock_count) { rsp->hdr.Status = STATUS_INVALID_PARAMETER; err = -EINVAL; goto out2; } Loading @@ -6616,10 +6621,8 @@ int smb2_lock(struct ksmbd_work *work) flags = le32_to_cpu(lock_ele[i].Flags); flock = smb_flock_init(filp); if (!flock) { rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED; if (!flock) goto out; } cmd = smb2_set_flock_flags(flock, flags); Loading Loading @@ -6657,8 +6660,7 @@ int smb2_lock(struct ksmbd_work *work) if (cmp_lock->fl->fl_type != F_UNLCK && flock->fl_type != F_UNLCK) { pr_err("conflict two locks in one request\n"); rsp->hdr.Status = STATUS_INVALID_PARAMETER; err = -EINVAL; goto out; } } Loading @@ -6666,19 +6668,19 @@ int smb2_lock(struct ksmbd_work *work) smb_lock = smb2_lock_init(flock, cmd, flags, &lock_list); if (!smb_lock) { rsp->hdr.Status = STATUS_INVALID_PARAMETER; err = -EINVAL; goto out; } } list_for_each_entry_safe(smb_lock, tmp, &lock_list, llist) { if (smb_lock->cmd < 0) { rsp->hdr.Status = STATUS_INVALID_PARAMETER; err = -EINVAL; goto out; } if (!(smb_lock->flags & SMB2_LOCKFLAG_MASK)) { rsp->hdr.Status = STATUS_INVALID_PARAMETER; err = -EINVAL; goto out; } Loading @@ -6686,7 +6688,7 @@ int smb2_lock(struct ksmbd_work *work) smb_lock->flags & SMB2_LOCKFLAG_UNLOCK) || (prior_lock == SMB2_LOCKFLAG_UNLOCK && !(smb_lock->flags & SMB2_LOCKFLAG_UNLOCK))) { rsp->hdr.Status = STATUS_INVALID_PARAMETER; err = -EINVAL; goto out; } Loading Loading @@ -6739,7 +6741,6 @@ int smb2_lock(struct ksmbd_work *work) spin_unlock(&conn->llist_lock); read_unlock(&conn_list_lock); pr_err("previous lock conflict with zero byte lock range\n"); rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED; goto out; } Loading @@ -6749,7 +6750,6 @@ int smb2_lock(struct ksmbd_work *work) spin_unlock(&conn->llist_lock); read_unlock(&conn_list_lock); pr_err("current lock conflict with zero byte lock range\n"); rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED; goto out; } Loading @@ -6761,8 +6761,6 @@ int smb2_lock(struct ksmbd_work *work) spin_unlock(&conn->llist_lock); read_unlock(&conn_list_lock); pr_err("Not allow lock operation on exclusive lock range\n"); rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED; goto out; } } Loading @@ -6785,19 +6783,19 @@ int smb2_lock(struct ksmbd_work *work) flock = smb_lock->fl; list_del(&smb_lock->llist); retry: err = vfs_lock_file(filp, smb_lock->cmd, flock, NULL); rc = vfs_lock_file(filp, smb_lock->cmd, flock, NULL); skip: if (flags & SMB2_LOCKFLAG_UNLOCK) { if (!err) { if (!rc) { ksmbd_debug(SMB, "File unlocked\n"); } else if (err == -ENOENT) { } else if (rc == -ENOENT) { rsp->hdr.Status = STATUS_NOT_LOCKED; goto out; } locks_free_lock(flock); kfree(smb_lock); } else { if (err == FILE_LOCK_DEFERRED) { if (rc == FILE_LOCK_DEFERRED) { void **argv; ksmbd_debug(SMB, Loading @@ -6815,12 +6813,11 @@ int smb2_lock(struct ksmbd_work *work) } argv[0] = flock; err = setup_async_work(work, rc = setup_async_work(work, smb2_remove_blocked_lock, argv); if (err) { rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES; if (rc) { err = -ENOMEM; goto out; } spin_lock(&fp->f_lock); Loading Loading @@ -6867,7 +6864,7 @@ int smb2_lock(struct ksmbd_work *work) list_del(&work->fp_entry); spin_unlock(&fp->f_lock); goto retry; } else if (!err) { } else if (!rc) { spin_lock(&work->conn->llist_lock); list_add_tail(&smb_lock->clist, &work->conn->lock_list); Loading @@ -6877,7 +6874,6 @@ int smb2_lock(struct ksmbd_work *work) list_add(&smb_lock->llist, &rollback_list); ksmbd_debug(SMB, "successful in taking lock\n"); } else { rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED; goto out; } } Loading @@ -6903,7 +6899,6 @@ int smb2_lock(struct ksmbd_work *work) list_for_each_entry_safe(smb_lock, tmp, &rollback_list, llist) { struct file_lock *rlock = NULL; int rc; rlock = smb_flock_init(filp); rlock->fl_type = F_UNLCK; Loading @@ -6926,7 +6921,19 @@ int smb2_lock(struct ksmbd_work *work) kfree(smb_lock); } out2: ksmbd_debug(SMB, "failed in taking lock(flags : %x)\n", flags); ksmbd_debug(SMB, "failed in taking lock(flags : %x), err : %d\n", flags, err); if (!rsp->hdr.Status) { if (err == -EINVAL) rsp->hdr.Status = STATUS_INVALID_PARAMETER; else if (err == -ENOMEM) rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES; else if (err == -ENOENT) rsp->hdr.Status = STATUS_FILE_CLOSED; else rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED; } smb2_set_err_rsp(work); ksmbd_fd_put(work, fp); return err; Loading Loading @@ -7071,6 +7078,7 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn, struct sockaddr_storage_rsp *sockaddr_storage; unsigned int flags; unsigned long long speed; struct sockaddr_in6 *csin6 = (struct sockaddr_in6 *)&conn->peer_addr; rtnl_lock(); for_each_netdev(&init_net, netdev) { Loading @@ -7086,8 +7094,6 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn, nii_rsp->IfIndex = cpu_to_le32(netdev->ifindex); nii_rsp->Capability = 0; if (netdev->num_tx_queues > 1) nii_rsp->Capability |= cpu_to_le32(RSS_CAPABLE); if (ksmbd_rdma_capable_netdev(netdev)) nii_rsp->Capability |= cpu_to_le32(RDMA_CAPABLE); Loading @@ -7112,7 +7118,8 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn, nii_rsp->SockAddr_Storage; memset(sockaddr_storage, 0, 128); if (conn->peer_addr.ss_family == PF_INET) { if (conn->peer_addr.ss_family == PF_INET || ipv6_addr_v4mapped(&csin6->sin6_addr)) { struct in_device *idev; sockaddr_storage->Family = cpu_to_le16(INTERNETWORK); Loading Loading @@ -8147,7 +8154,8 @@ void smb3_set_sign_rsp(struct ksmbd_work *work) len = ALIGN(len, 8); } if (le16_to_cpu(hdr->Command) == SMB2_SESSION_SETUP_HE) { if (conn->binding == false && le16_to_cpu(hdr->Command) == SMB2_SESSION_SETUP_HE) { signing_key = work->sess->smb3signingkey; } else { chann = lookup_chann_list(work->sess, work->conn); Loading Loading
fs/ksmbd/smb2pdu.c +45 −37 Original line number Diff line number Diff line Loading @@ -2768,8 +2768,13 @@ int smb2_open(struct ksmbd_work *work) if (!file_present) { rc = smb2_creat(work, &path, name, open_flags, posix_mode, req->CreateOptions & FILE_DIRECTORY_FILE_LE); if (rc) if (rc) { if (rc == -ENOENT) { rc = -EIO; rsp->hdr.Status = STATUS_OBJECT_PATH_NOT_FOUND; } goto err_out; } created = true; user_ns = mnt_user_ns(path.mnt); Loading Loading @@ -6582,7 +6587,7 @@ int smb2_lock(struct ksmbd_work *work) int lock_count; int flags = 0; int cmd = 0; int err = 0, i; int err = -EIO, i, rc = 0; u64 lock_start, lock_length; struct ksmbd_lock *smb_lock = NULL, *cmp_lock, *tmp, *tmp2; struct ksmbd_conn *conn; Loading @@ -6598,7 +6603,7 @@ int smb2_lock(struct ksmbd_work *work) if (!fp) { ksmbd_debug(SMB, "Invalid file id for lock : %llu\n", le64_to_cpu(req->VolatileFileId)); rsp->hdr.Status = STATUS_FILE_CLOSED; err = -ENOENT; goto out2; } Loading @@ -6608,7 +6613,7 @@ int smb2_lock(struct ksmbd_work *work) ksmbd_debug(SMB, "lock count is %d\n", lock_count); if (!lock_count) { rsp->hdr.Status = STATUS_INVALID_PARAMETER; err = -EINVAL; goto out2; } Loading @@ -6616,10 +6621,8 @@ int smb2_lock(struct ksmbd_work *work) flags = le32_to_cpu(lock_ele[i].Flags); flock = smb_flock_init(filp); if (!flock) { rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED; if (!flock) goto out; } cmd = smb2_set_flock_flags(flock, flags); Loading Loading @@ -6657,8 +6660,7 @@ int smb2_lock(struct ksmbd_work *work) if (cmp_lock->fl->fl_type != F_UNLCK && flock->fl_type != F_UNLCK) { pr_err("conflict two locks in one request\n"); rsp->hdr.Status = STATUS_INVALID_PARAMETER; err = -EINVAL; goto out; } } Loading @@ -6666,19 +6668,19 @@ int smb2_lock(struct ksmbd_work *work) smb_lock = smb2_lock_init(flock, cmd, flags, &lock_list); if (!smb_lock) { rsp->hdr.Status = STATUS_INVALID_PARAMETER; err = -EINVAL; goto out; } } list_for_each_entry_safe(smb_lock, tmp, &lock_list, llist) { if (smb_lock->cmd < 0) { rsp->hdr.Status = STATUS_INVALID_PARAMETER; err = -EINVAL; goto out; } if (!(smb_lock->flags & SMB2_LOCKFLAG_MASK)) { rsp->hdr.Status = STATUS_INVALID_PARAMETER; err = -EINVAL; goto out; } Loading @@ -6686,7 +6688,7 @@ int smb2_lock(struct ksmbd_work *work) smb_lock->flags & SMB2_LOCKFLAG_UNLOCK) || (prior_lock == SMB2_LOCKFLAG_UNLOCK && !(smb_lock->flags & SMB2_LOCKFLAG_UNLOCK))) { rsp->hdr.Status = STATUS_INVALID_PARAMETER; err = -EINVAL; goto out; } Loading Loading @@ -6739,7 +6741,6 @@ int smb2_lock(struct ksmbd_work *work) spin_unlock(&conn->llist_lock); read_unlock(&conn_list_lock); pr_err("previous lock conflict with zero byte lock range\n"); rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED; goto out; } Loading @@ -6749,7 +6750,6 @@ int smb2_lock(struct ksmbd_work *work) spin_unlock(&conn->llist_lock); read_unlock(&conn_list_lock); pr_err("current lock conflict with zero byte lock range\n"); rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED; goto out; } Loading @@ -6761,8 +6761,6 @@ int smb2_lock(struct ksmbd_work *work) spin_unlock(&conn->llist_lock); read_unlock(&conn_list_lock); pr_err("Not allow lock operation on exclusive lock range\n"); rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED; goto out; } } Loading @@ -6785,19 +6783,19 @@ int smb2_lock(struct ksmbd_work *work) flock = smb_lock->fl; list_del(&smb_lock->llist); retry: err = vfs_lock_file(filp, smb_lock->cmd, flock, NULL); rc = vfs_lock_file(filp, smb_lock->cmd, flock, NULL); skip: if (flags & SMB2_LOCKFLAG_UNLOCK) { if (!err) { if (!rc) { ksmbd_debug(SMB, "File unlocked\n"); } else if (err == -ENOENT) { } else if (rc == -ENOENT) { rsp->hdr.Status = STATUS_NOT_LOCKED; goto out; } locks_free_lock(flock); kfree(smb_lock); } else { if (err == FILE_LOCK_DEFERRED) { if (rc == FILE_LOCK_DEFERRED) { void **argv; ksmbd_debug(SMB, Loading @@ -6815,12 +6813,11 @@ int smb2_lock(struct ksmbd_work *work) } argv[0] = flock; err = setup_async_work(work, rc = setup_async_work(work, smb2_remove_blocked_lock, argv); if (err) { rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES; if (rc) { err = -ENOMEM; goto out; } spin_lock(&fp->f_lock); Loading Loading @@ -6867,7 +6864,7 @@ int smb2_lock(struct ksmbd_work *work) list_del(&work->fp_entry); spin_unlock(&fp->f_lock); goto retry; } else if (!err) { } else if (!rc) { spin_lock(&work->conn->llist_lock); list_add_tail(&smb_lock->clist, &work->conn->lock_list); Loading @@ -6877,7 +6874,6 @@ int smb2_lock(struct ksmbd_work *work) list_add(&smb_lock->llist, &rollback_list); ksmbd_debug(SMB, "successful in taking lock\n"); } else { rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED; goto out; } } Loading @@ -6903,7 +6899,6 @@ int smb2_lock(struct ksmbd_work *work) list_for_each_entry_safe(smb_lock, tmp, &rollback_list, llist) { struct file_lock *rlock = NULL; int rc; rlock = smb_flock_init(filp); rlock->fl_type = F_UNLCK; Loading @@ -6926,7 +6921,19 @@ int smb2_lock(struct ksmbd_work *work) kfree(smb_lock); } out2: ksmbd_debug(SMB, "failed in taking lock(flags : %x)\n", flags); ksmbd_debug(SMB, "failed in taking lock(flags : %x), err : %d\n", flags, err); if (!rsp->hdr.Status) { if (err == -EINVAL) rsp->hdr.Status = STATUS_INVALID_PARAMETER; else if (err == -ENOMEM) rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES; else if (err == -ENOENT) rsp->hdr.Status = STATUS_FILE_CLOSED; else rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED; } smb2_set_err_rsp(work); ksmbd_fd_put(work, fp); return err; Loading Loading @@ -7071,6 +7078,7 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn, struct sockaddr_storage_rsp *sockaddr_storage; unsigned int flags; unsigned long long speed; struct sockaddr_in6 *csin6 = (struct sockaddr_in6 *)&conn->peer_addr; rtnl_lock(); for_each_netdev(&init_net, netdev) { Loading @@ -7086,8 +7094,6 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn, nii_rsp->IfIndex = cpu_to_le32(netdev->ifindex); nii_rsp->Capability = 0; if (netdev->num_tx_queues > 1) nii_rsp->Capability |= cpu_to_le32(RSS_CAPABLE); if (ksmbd_rdma_capable_netdev(netdev)) nii_rsp->Capability |= cpu_to_le32(RDMA_CAPABLE); Loading @@ -7112,7 +7118,8 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn, nii_rsp->SockAddr_Storage; memset(sockaddr_storage, 0, 128); if (conn->peer_addr.ss_family == PF_INET) { if (conn->peer_addr.ss_family == PF_INET || ipv6_addr_v4mapped(&csin6->sin6_addr)) { struct in_device *idev; sockaddr_storage->Family = cpu_to_le16(INTERNETWORK); Loading Loading @@ -8147,7 +8154,8 @@ void smb3_set_sign_rsp(struct ksmbd_work *work) len = ALIGN(len, 8); } if (le16_to_cpu(hdr->Command) == SMB2_SESSION_SETUP_HE) { if (conn->binding == false && le16_to_cpu(hdr->Command) == SMB2_SESSION_SETUP_HE) { signing_key = work->sess->smb3signingkey; } else { chann = lookup_chann_list(work->sess, work->conn); Loading