Commit 91b436fc authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'v6.18-rc-part2-smb-client-fixes' of git://git.samba.org/sfrench/cifs-2.6

Pull more smb client updates from Steve French:

 - fix i_size in fallocate

 - two truncate fixes

 - utime fix

 - minor cleanups

 - SMB1 fixes

 - improve error check in read

 - improve perf of copy file_range (copy_chunk)

* tag 'v6.18-rc-part2-smb-client-fixes' of git://git.samba.org/sfrench/cifs-2.6:
  cifs: update internal version number
  cifs: Add comments for DeletePending assignments in open functions
  cifs: Add fallback code path for cifs_mkdir_setinfo()
  cifs: Allow fallback code in smb_set_file_info() also for directories
  cifs: Query EA $LXMOD in cifs_query_path_info() for WSL reparse points
  smb: client: remove cfids_invalidation_worker
  smb: client: remove redudant assignment in cifs_strict_fsync()
  smb: client: fix race with fallocate(2) and AIO+DIO
  smb: client: fix missing timestamp updates after utime(2)
  smb: client: fix missing timestamp updates after ftruncate(2)
  smb: client: fix missing timestamp updates with O_TRUNC
  cifs: Fix copy_to_iter return value check
  smb: client: batch SRV_COPYCHUNK entries to cut round trips
  smb: client: Omit an if branch in smb2_find_smb_tcon()
  smb: client: Return directly after a failed genlmsg_new() in cifs_swn_send_register_message()
  smb: client: Use common code in cifs_do_create()
  smb: client: Improve unlocking of a mutex in cifs_get_swn_reg()
  smb: client: Return a status code only as a constant in cifs_spnego_key_instantiate()
  smb: client: Use common code in cifs_lookup()
  smb: client: Reduce the scopes for a few variables in two functions
parents 917167ed b30c32c7
Loading
Loading
Loading
Loading
+9 −28
Original line number Diff line number Diff line
@@ -562,8 +562,8 @@ void invalidate_all_cached_dirs(struct cifs_tcon *tcon)

	/*
	 * Mark all the cfids as closed, and move them to the cfids->dying list.
	 * They'll be cleaned up later by cfids_invalidation_worker. Take
	 * a reference to each cfid during this process.
	 * They'll be cleaned up by laundromat.  Take a reference to each cfid
	 * during this process.
	 */
	spin_lock(&cfids->cfid_list_lock);
	list_for_each_entry_safe(cfid, q, &cfids->entries, entry) {
@@ -580,12 +580,11 @@ void invalidate_all_cached_dirs(struct cifs_tcon *tcon)
		} else
			kref_get(&cfid->refcount);
	}
	/*
	 * Queue dropping of the dentries once locks have been dropped
	 */
	if (!list_empty(&cfids->dying))
		queue_work(cfid_put_wq, &cfids->invalidation_work);
	spin_unlock(&cfids->cfid_list_lock);

	/* run laundromat unconditionally now as there might have been previously queued work */
	mod_delayed_work(cfid_put_wq, &cfids->laundromat_work, 0);
	flush_delayed_work(&cfids->laundromat_work);
}

static void
@@ -715,25 +714,6 @@ static void free_cached_dir(struct cached_fid *cfid)
	kfree(cfid);
}

static void cfids_invalidation_worker(struct work_struct *work)
{
	struct cached_fids *cfids = container_of(work, struct cached_fids,
						 invalidation_work);
	struct cached_fid *cfid, *q;
	LIST_HEAD(entry);

	spin_lock(&cfids->cfid_list_lock);
	/* move cfids->dying to the local list */
	list_cut_before(&entry, &cfids->dying, &cfids->dying);
	spin_unlock(&cfids->cfid_list_lock);

	list_for_each_entry_safe(cfid, q, &entry, entry) {
		list_del(&cfid->entry);
		/* Drop the ref-count acquired in invalidate_all_cached_dirs */
		kref_put(&cfid->refcount, smb2_close_cached_fid);
	}
}

static void cfids_laundromat_worker(struct work_struct *work)
{
	struct cached_fids *cfids;
@@ -743,6 +723,9 @@ static void cfids_laundromat_worker(struct work_struct *work)
	cfids = container_of(work, struct cached_fids, laundromat_work.work);

	spin_lock(&cfids->cfid_list_lock);
	/* move cfids->dying to the local list */
	list_cut_before(&entry, &cfids->dying, &cfids->dying);

	list_for_each_entry_safe(cfid, q, &cfids->entries, entry) {
		if (cfid->last_access_time &&
		    time_after(jiffies, cfid->last_access_time + HZ * dir_cache_timeout)) {
@@ -796,7 +779,6 @@ struct cached_fids *init_cached_dirs(void)
	INIT_LIST_HEAD(&cfids->entries);
	INIT_LIST_HEAD(&cfids->dying);

	INIT_WORK(&cfids->invalidation_work, cfids_invalidation_worker);
	INIT_DELAYED_WORK(&cfids->laundromat_work, cfids_laundromat_worker);
	queue_delayed_work(cfid_put_wq, &cfids->laundromat_work,
			   dir_cache_timeout * HZ);
@@ -820,7 +802,6 @@ void free_cached_dirs(struct cached_fids *cfids)
		return;

	cancel_delayed_work_sync(&cfids->laundromat_work);
	cancel_work_sync(&cfids->invalidation_work);

	spin_lock(&cfids->cfid_list_lock);
	list_for_each_entry_safe(cfid, q, &cfids->entries, entry) {
+0 −1
Original line number Diff line number Diff line
@@ -62,7 +62,6 @@ struct cached_fids {
	int num_entries;
	struct list_head entries;
	struct list_head dying;
	struct work_struct invalidation_work;
	struct delayed_work laundromat_work;
	/* aggregate accounting for all cached dirents under this tcon */
	atomic_long_t total_dirents_entries;
+3 −9
Original line number Diff line number Diff line
@@ -24,20 +24,14 @@ static const struct cred *spnego_cred;
static int
cifs_spnego_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
{
	char *payload;
	int ret;
	char *payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL);

	ret = -ENOMEM;
	payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL);
	if (!payload)
		goto error;
		return -ENOMEM;

	/* attach the data */
	key->payload.data[0] = payload;
	ret = 0;

error:
	return ret;
	return 0;
}

static void
+8 −12
Original line number Diff line number Diff line
@@ -82,10 +82,8 @@ static int cifs_swn_send_register_message(struct cifs_swn_reg *swnreg)
	int ret;

	skb = genlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
	if (skb == NULL) {
		ret = -ENOMEM;
		goto fail;
	}
	if (!skb)
		return -ENOMEM;

	hdr = genlmsg_put(skb, 0, 0, &cifs_genl_family, 0, CIFS_GENL_CMD_SWN_REGISTER);
	if (hdr == NULL) {
@@ -172,7 +170,6 @@ static int cifs_swn_send_register_message(struct cifs_swn_reg *swnreg)
nlmsg_fail:
	genlmsg_cancel(skb, hdr);
	nlmsg_free(skb);
fail:
	return ret;
}

@@ -313,17 +310,15 @@ static struct cifs_swn_reg *cifs_get_swn_reg(struct cifs_tcon *tcon)
	reg = cifs_find_swn_reg(tcon);
	if (!IS_ERR(reg)) {
		kref_get(&reg->ref_count);
		mutex_unlock(&cifs_swnreg_idr_mutex);
		return reg;
		goto unlock;
	} else if (PTR_ERR(reg) != -EEXIST) {
		mutex_unlock(&cifs_swnreg_idr_mutex);
		return reg;
		goto unlock;
	}

	reg = kmalloc(sizeof(struct cifs_swn_reg), GFP_ATOMIC);
	if (reg == NULL) {
		mutex_unlock(&cifs_swnreg_idr_mutex);
		return ERR_PTR(-ENOMEM);
		ret = -ENOMEM;
		goto fail_unlock;
	}

	kref_init(&reg->ref_count);
@@ -354,7 +349,7 @@ static struct cifs_swn_reg *cifs_get_swn_reg(struct cifs_tcon *tcon)
	reg->ip_notify = (tcon->capabilities & SMB2_SHARE_CAP_SCALEOUT);

	reg->tcon = tcon;

unlock:
	mutex_unlock(&cifs_swnreg_idr_mutex);

	return reg;
@@ -365,6 +360,7 @@ static struct cifs_swn_reg *cifs_get_swn_reg(struct cifs_tcon *tcon)
	idr_remove(&cifs_swnreg_idr, reg->id);
fail:
	kfree(reg);
fail_unlock:
	mutex_unlock(&cifs_swnreg_idr_mutex);
	return ERR_PTR(ret);
}
+19 −3
Original line number Diff line number Diff line
@@ -392,11 +392,27 @@ static long cifs_fallocate(struct file *file, int mode, loff_t off, loff_t len)
	struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file);
	struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
	struct TCP_Server_Info *server = tcon->ses->server;
	struct inode *inode = file_inode(file);
	int rc;

	if (server->ops->fallocate)
		return server->ops->fallocate(file, tcon, mode, off, len);

	if (!server->ops->fallocate)
		return -EOPNOTSUPP;

	rc = inode_lock_killable(inode);
	if (rc)
		return rc;

	netfs_wait_for_outstanding_io(inode);

	rc = file_modified(file);
	if (rc)
		goto out_unlock;

	rc = server->ops->fallocate(file, tcon, mode, off, len);

out_unlock:
	inode_unlock(inode);
	return rc;
}

static int cifs_permission(struct mnt_idmap *idmap,
Loading