Skip to content

Commit 91b436f

Browse files
committed
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
2 parents 917167e + b30c32c commit 91b436f

File tree

18 files changed

+522
-329
lines changed

18 files changed

+522
-329
lines changed

fs/smb/client/cached_dir.c

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -562,8 +562,8 @@ void invalidate_all_cached_dirs(struct cifs_tcon *tcon)
562562

563563
/*
564564
* Mark all the cfids as closed, and move them to the cfids->dying list.
565-
* They'll be cleaned up later by cfids_invalidation_worker. Take
566-
* a reference to each cfid during this process.
565+
* They'll be cleaned up by laundromat. Take a reference to each cfid
566+
* during this process.
567567
*/
568568
spin_lock(&cfids->cfid_list_lock);
569569
list_for_each_entry_safe(cfid, q, &cfids->entries, entry) {
@@ -580,12 +580,11 @@ void invalidate_all_cached_dirs(struct cifs_tcon *tcon)
580580
} else
581581
kref_get(&cfid->refcount);
582582
}
583-
/*
584-
* Queue dropping of the dentries once locks have been dropped
585-
*/
586-
if (!list_empty(&cfids->dying))
587-
queue_work(cfid_put_wq, &cfids->invalidation_work);
588583
spin_unlock(&cfids->cfid_list_lock);
584+
585+
/* run laundromat unconditionally now as there might have been previously queued work */
586+
mod_delayed_work(cfid_put_wq, &cfids->laundromat_work, 0);
587+
flush_delayed_work(&cfids->laundromat_work);
589588
}
590589

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

718-
static void cfids_invalidation_worker(struct work_struct *work)
719-
{
720-
struct cached_fids *cfids = container_of(work, struct cached_fids,
721-
invalidation_work);
722-
struct cached_fid *cfid, *q;
723-
LIST_HEAD(entry);
724-
725-
spin_lock(&cfids->cfid_list_lock);
726-
/* move cfids->dying to the local list */
727-
list_cut_before(&entry, &cfids->dying, &cfids->dying);
728-
spin_unlock(&cfids->cfid_list_lock);
729-
730-
list_for_each_entry_safe(cfid, q, &entry, entry) {
731-
list_del(&cfid->entry);
732-
/* Drop the ref-count acquired in invalidate_all_cached_dirs */
733-
kref_put(&cfid->refcount, smb2_close_cached_fid);
734-
}
735-
}
736-
737717
static void cfids_laundromat_worker(struct work_struct *work)
738718
{
739719
struct cached_fids *cfids;
@@ -743,6 +723,9 @@ static void cfids_laundromat_worker(struct work_struct *work)
743723
cfids = container_of(work, struct cached_fids, laundromat_work.work);
744724

745725
spin_lock(&cfids->cfid_list_lock);
726+
/* move cfids->dying to the local list */
727+
list_cut_before(&entry, &cfids->dying, &cfids->dying);
728+
746729
list_for_each_entry_safe(cfid, q, &cfids->entries, entry) {
747730
if (cfid->last_access_time &&
748731
time_after(jiffies, cfid->last_access_time + HZ * dir_cache_timeout)) {
@@ -796,7 +779,6 @@ struct cached_fids *init_cached_dirs(void)
796779
INIT_LIST_HEAD(&cfids->entries);
797780
INIT_LIST_HEAD(&cfids->dying);
798781

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

822804
cancel_delayed_work_sync(&cfids->laundromat_work);
823-
cancel_work_sync(&cfids->invalidation_work);
824805

825806
spin_lock(&cfids->cfid_list_lock);
826807
list_for_each_entry_safe(cfid, q, &cfids->entries, entry) {

fs/smb/client/cached_dir.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ struct cached_fids {
6262
int num_entries;
6363
struct list_head entries;
6464
struct list_head dying;
65-
struct work_struct invalidation_work;
6665
struct delayed_work laundromat_work;
6766
/* aggregate accounting for all cached dirents under this tcon */
6867
atomic_long_t total_dirents_entries;

fs/smb/client/cifs_spnego.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,14 @@ static const struct cred *spnego_cred;
2424
static int
2525
cifs_spnego_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
2626
{
27-
char *payload;
28-
int ret;
27+
char *payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL);
2928

30-
ret = -ENOMEM;
31-
payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL);
3229
if (!payload)
33-
goto error;
30+
return -ENOMEM;
3431

3532
/* attach the data */
3633
key->payload.data[0] = payload;
37-
ret = 0;
38-
39-
error:
40-
return ret;
34+
return 0;
4135
}
4236

4337
static void

fs/smb/client/cifs_swn.c

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,8 @@ static int cifs_swn_send_register_message(struct cifs_swn_reg *swnreg)
8282
int ret;
8383

8484
skb = genlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
85-
if (skb == NULL) {
86-
ret = -ENOMEM;
87-
goto fail;
88-
}
85+
if (!skb)
86+
return -ENOMEM;
8987

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

@@ -313,17 +310,15 @@ static struct cifs_swn_reg *cifs_get_swn_reg(struct cifs_tcon *tcon)
313310
reg = cifs_find_swn_reg(tcon);
314311
if (!IS_ERR(reg)) {
315312
kref_get(&reg->ref_count);
316-
mutex_unlock(&cifs_swnreg_idr_mutex);
317-
return reg;
313+
goto unlock;
318314
} else if (PTR_ERR(reg) != -EEXIST) {
319-
mutex_unlock(&cifs_swnreg_idr_mutex);
320-
return reg;
315+
goto unlock;
321316
}
322317

323318
reg = kmalloc(sizeof(struct cifs_swn_reg), GFP_ATOMIC);
324319
if (reg == NULL) {
325-
mutex_unlock(&cifs_swnreg_idr_mutex);
326-
return ERR_PTR(-ENOMEM);
320+
ret = -ENOMEM;
321+
goto fail_unlock;
327322
}
328323

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

356351
reg->tcon = tcon;
357-
352+
unlock:
358353
mutex_unlock(&cifs_swnreg_idr_mutex);
359354

360355
return reg;
@@ -365,6 +360,7 @@ static struct cifs_swn_reg *cifs_get_swn_reg(struct cifs_tcon *tcon)
365360
idr_remove(&cifs_swnreg_idr, reg->id);
366361
fail:
367362
kfree(reg);
363+
fail_unlock:
368364
mutex_unlock(&cifs_swnreg_idr_mutex);
369365
return ERR_PTR(ret);
370366
}

fs/smb/client/cifsfs.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -392,11 +392,27 @@ static long cifs_fallocate(struct file *file, int mode, loff_t off, loff_t len)
392392
struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file);
393393
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
394394
struct TCP_Server_Info *server = tcon->ses->server;
395+
struct inode *inode = file_inode(file);
396+
int rc;
397+
398+
if (!server->ops->fallocate)
399+
return -EOPNOTSUPP;
400+
401+
rc = inode_lock_killable(inode);
402+
if (rc)
403+
return rc;
404+
405+
netfs_wait_for_outstanding_io(inode);
395406

396-
if (server->ops->fallocate)
397-
return server->ops->fallocate(file, tcon, mode, off, len);
407+
rc = file_modified(file);
408+
if (rc)
409+
goto out_unlock;
410+
411+
rc = server->ops->fallocate(file, tcon, mode, off, len);
398412

399-
return -EOPNOTSUPP;
413+
out_unlock:
414+
inode_unlock(inode);
415+
return rc;
400416
}
401417

402418
static int cifs_permission(struct mnt_idmap *idmap,

fs/smb/client/cifsfs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,6 @@ extern const struct export_operations cifs_export_ops;
145145
#endif /* CONFIG_CIFS_NFSD_EXPORT */
146146

147147
/* when changing internal version - update following two lines at same time */
148-
#define SMB3_PRODUCT_BUILD 56
149-
#define CIFS_VERSION "2.56"
148+
#define SMB3_PRODUCT_BUILD 57
149+
#define CIFS_VERSION "2.57"
150150
#endif /* _CIFSFS_H */

fs/smb/client/cifsglob.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1566,6 +1566,11 @@ struct cifsFileInfo *cifsFileInfo_get(struct cifsFileInfo *cifs_file);
15661566
void _cifsFileInfo_put(struct cifsFileInfo *cifs_file, bool wait_oplock_hdlr,
15671567
bool offload);
15681568
void cifsFileInfo_put(struct cifsFileInfo *cifs_file);
1569+
int cifs_file_flush(const unsigned int xid, struct inode *inode,
1570+
struct cifsFileInfo *cfile);
1571+
int cifs_file_set_size(const unsigned int xid, struct dentry *dentry,
1572+
const char *full_path, struct cifsFileInfo *open_file,
1573+
loff_t size);
15691574

15701575
#define CIFS_CACHE_READ_FLG 1
15711576
#define CIFS_CACHE_HANDLE_FLG 2

fs/smb/client/cifssmb.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,7 +1163,7 @@ SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
11631163
cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
11641164
pfile_info->EndOfFile = pfile_info->AllocationSize;
11651165
pfile_info->NumberOfLinks = cpu_to_le32(1);
1166-
pfile_info->DeletePending = 0;
1166+
pfile_info->DeletePending = 0; /* successful open = not delete pending */
11671167
}
11681168
}
11691169

@@ -1288,7 +1288,7 @@ CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
12881288
buf->AllocationSize = rsp->AllocationSize;
12891289
buf->EndOfFile = rsp->EndOfFile;
12901290
buf->NumberOfLinks = cpu_to_le32(1);
1291-
buf->DeletePending = 0;
1291+
buf->DeletePending = 0; /* successful open = not delete pending */
12921292
}
12931293

12941294
cifs_buf_release(req);

fs/smb/client/dir.c

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,8 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned
200200

201201
full_path = build_path_from_dentry(direntry, page);
202202
if (IS_ERR(full_path)) {
203-
free_dentry_path(page);
204-
return PTR_ERR(full_path);
203+
rc = PTR_ERR(full_path);
204+
goto out;
205205
}
206206

207207
/* If we're caching, we need to be able to fill in around partial writes. */
@@ -678,7 +678,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
678678
const char *full_path;
679679
void *page;
680680
int retry_count = 0;
681-
struct cached_fid *cfid = NULL;
681+
struct dentry *de;
682682

683683
xid = get_xid();
684684

@@ -690,16 +690,15 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
690690
cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
691691
tlink = cifs_sb_tlink(cifs_sb);
692692
if (IS_ERR(tlink)) {
693-
free_xid(xid);
694-
return ERR_CAST(tlink);
693+
de = ERR_CAST(tlink);
694+
goto free_xid;
695695
}
696696
pTcon = tlink_tcon(tlink);
697697

698698
rc = check_name(direntry, pTcon);
699699
if (unlikely(rc)) {
700-
cifs_put_tlink(tlink);
701-
free_xid(xid);
702-
return ERR_PTR(rc);
700+
de = ERR_PTR(rc);
701+
goto put_tlink;
703702
}
704703

705704
/* can not grab the rename sem here since it would
@@ -708,15 +707,15 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
708707
page = alloc_dentry_path();
709708
full_path = build_path_from_dentry(direntry, page);
710709
if (IS_ERR(full_path)) {
711-
cifs_put_tlink(tlink);
712-
free_xid(xid);
713-
free_dentry_path(page);
714-
return ERR_CAST(full_path);
710+
de = ERR_CAST(full_path);
711+
goto free_dentry_path;
715712
}
716713

717714
if (d_really_is_positive(direntry)) {
718715
cifs_dbg(FYI, "non-NULL inode in lookup\n");
719716
} else {
717+
struct cached_fid *cfid = NULL;
718+
720719
cifs_dbg(FYI, "NULL inode in lookup\n");
721720

722721
/*
@@ -775,25 +774,27 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
775774
}
776775

777776
out:
777+
de = d_splice_alias(newInode, direntry);
778+
free_dentry_path:
778779
free_dentry_path(page);
780+
put_tlink:
779781
cifs_put_tlink(tlink);
782+
free_xid:
780783
free_xid(xid);
781-
return d_splice_alias(newInode, direntry);
784+
return de;
782785
}
783786

784787
static int
785788
cifs_d_revalidate(struct inode *dir, const struct qstr *name,
786789
struct dentry *direntry, unsigned int flags)
787790
{
788-
struct inode *inode = NULL;
789-
struct cached_fid *cfid;
790-
int rc;
791-
792791
if (flags & LOOKUP_RCU)
793792
return -ECHILD;
794793

795794
if (d_really_is_positive(direntry)) {
796-
inode = d_inode(direntry);
795+
int rc;
796+
struct inode *inode = d_inode(direntry);
797+
797798
if ((flags & LOOKUP_REVAL) && !CIFS_CACHE_READ(CIFS_I(inode)))
798799
CIFS_I(inode)->time = 0; /* force reval */
799800

@@ -836,6 +837,7 @@ cifs_d_revalidate(struct inode *dir, const struct qstr *name,
836837
} else {
837838
struct cifs_sb_info *cifs_sb = CIFS_SB(dir->i_sb);
838839
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
840+
struct cached_fid *cfid;
839841

840842
if (!open_cached_dir_by_dentry(tcon, direntry->d_parent, &cfid)) {
841843
/*

0 commit comments

Comments
 (0)