Unverified Commit a8ab5293 authored by Steve French's avatar Steve French Committed by GitHub
Browse files

Merge pull request #63 from namjaejeon/cifsd-for-next

ksmbd-fixes
parents 9a5ca188 f1abdb78
Loading
Loading
Loading
Loading
+45 −37
Original line number Diff line number Diff line
@@ -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);
@@ -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;
@@ -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;
	}

@@ -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;
	}

@@ -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);

@@ -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;
				}
			}
@@ -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;
		}

@@ -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;
		}

@@ -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;
				}

@@ -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;
				}

@@ -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;
				}
			}
@@ -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,
@@ -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);
@@ -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);
@@ -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;
			}
		}
@@ -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;
@@ -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;
@@ -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) {
@@ -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);

@@ -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);
@@ -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);