Skip to content

Commit 8e938e3

Browse files
committed
Merge tag '6.9-rc-smb3-client-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6
Pull smb client fixes from Steve French: - Various get_inode_info_fixes - Fix for querying xattrs of cached dirs - Four minor cleanup fixes (including adding some header corrections and a missing flag) - Performance improvement for deferred close - Two query interface fixes * tag '6.9-rc-smb3-client-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6: smb311: additional compression flag defined in updated protocol spec smb311: correct incorrect offset field in compression header cifs: Move some extern decls from .c files to .h cifs: remove redundant variable assignment cifs: fixes for get_inode_info cifs: open_cached_dir(): add FILE_READ_EA to desired access cifs: reduce warning log level for server not advertising interfaces cifs: make sure server interfaces are requested only for SMB3+ cifs: defer close file handles having RH lease
2 parents 7ee0490 + e56bc74 commit 8e938e3

File tree

11 files changed

+54
-39
lines changed

11 files changed

+54
-39
lines changed

fs/smb/client/cached_dir.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,8 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
239239
.tcon = tcon,
240240
.path = path,
241241
.create_options = cifs_create_options(cifs_sb, CREATE_NOT_FILE),
242-
.desired_access = FILE_READ_DATA | FILE_READ_ATTRIBUTES,
242+
.desired_access = FILE_READ_DATA | FILE_READ_ATTRIBUTES |
243+
FILE_READ_EA,
243244
.disposition = FILE_OPEN,
244245
.fid = pfid,
245246
.replay = !!(retries),

fs/smb/client/cifsfs.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,10 +151,6 @@ MODULE_PARM_DESC(disable_legacy_dialects, "To improve security it may be "
151151
"vers=1.0 (CIFS/SMB1) and vers=2.0 are weaker"
152152
" and less secure. Default: n/N/0");
153153

154-
extern mempool_t *cifs_sm_req_poolp;
155-
extern mempool_t *cifs_req_poolp;
156-
extern mempool_t *cifs_mid_poolp;
157-
158154
struct workqueue_struct *cifsiod_wq;
159155
struct workqueue_struct *decrypt_wq;
160156
struct workqueue_struct *fileinfo_put_wq;

fs/smb/client/cifsglob.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,9 @@ struct smb_version_operations {
355355
/* informational QFS call */
356356
void (*qfs_tcon)(const unsigned int, struct cifs_tcon *,
357357
struct cifs_sb_info *);
358+
/* query for server interfaces */
359+
int (*query_server_interfaces)(const unsigned int, struct cifs_tcon *,
360+
bool);
358361
/* check if a path is accessible or not */
359362
int (*is_path_accessible)(const unsigned int, struct cifs_tcon *,
360363
struct cifs_sb_info *, const char *);
@@ -2104,6 +2107,8 @@ extern struct workqueue_struct *cifsoplockd_wq;
21042107
extern struct workqueue_struct *deferredclose_wq;
21052108
extern __u32 cifs_lock_secret;
21062109

2110+
extern mempool_t *cifs_sm_req_poolp;
2111+
extern mempool_t *cifs_req_poolp;
21072112
extern mempool_t *cifs_mid_poolp;
21082113

21092114
/* Operations for different SMB versions */

fs/smb/client/connect.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,6 @@
5252
#include "fs_context.h"
5353
#include "cifs_swn.h"
5454

55-
extern mempool_t *cifs_req_poolp;
56-
extern bool disable_legacy_dialects;
57-
5855
/* FIXME: should these be tunable? */
5956
#define TLINK_ERROR_EXPIRE (1 * HZ)
6057
#define TLINK_IDLE_EXPIRE (600 * HZ)
@@ -123,12 +120,16 @@ static void smb2_query_server_interfaces(struct work_struct *work)
123120
struct cifs_tcon *tcon = container_of(work,
124121
struct cifs_tcon,
125122
query_interfaces.work);
123+
struct TCP_Server_Info *server = tcon->ses->server;
126124

127125
/*
128126
* query server network interfaces, in case they change
129127
*/
128+
if (!server->ops->query_server_interfaces)
129+
return;
130+
130131
xid = get_xid();
131-
rc = SMB3_request_interfaces(xid, tcon, false);
132+
rc = server->ops->query_server_interfaces(xid, tcon, false);
132133
free_xid(xid);
133134

134135
if (rc) {

fs/smb/client/file.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,6 @@ struct cifsFileInfo *cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
486486
cfile->uid = current_fsuid();
487487
cfile->dentry = dget(dentry);
488488
cfile->f_flags = file->f_flags;
489-
cfile->status_file_deleted = false;
490489
cfile->invalidHandle = false;
491490
cfile->deferred_close_scheduled = false;
492491
cfile->tlink = cifs_get_tlink(tlink);
@@ -1073,6 +1072,19 @@ void smb2_deferred_work_close(struct work_struct *work)
10731072
_cifsFileInfo_put(cfile, true, false);
10741073
}
10751074

1075+
static bool
1076+
smb2_can_defer_close(struct inode *inode, struct cifs_deferred_close *dclose)
1077+
{
1078+
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1079+
struct cifsInodeInfo *cinode = CIFS_I(inode);
1080+
1081+
return (cifs_sb->ctx->closetimeo && cinode->lease_granted && dclose &&
1082+
(cinode->oplock == CIFS_CACHE_RHW_FLG ||
1083+
cinode->oplock == CIFS_CACHE_RH_FLG) &&
1084+
!test_bit(CIFS_INO_CLOSE_ON_LOCK, &cinode->flags));
1085+
1086+
}
1087+
10761088
int cifs_close(struct inode *inode, struct file *file)
10771089
{
10781090
struct cifsFileInfo *cfile;
@@ -1086,10 +1098,8 @@ int cifs_close(struct inode *inode, struct file *file)
10861098
cfile = file->private_data;
10871099
file->private_data = NULL;
10881100
dclose = kmalloc(sizeof(struct cifs_deferred_close), GFP_KERNEL);
1089-
if ((cifs_sb->ctx->closetimeo && cinode->oplock == CIFS_CACHE_RHW_FLG)
1090-
&& cinode->lease_granted &&
1091-
!test_bit(CIFS_INO_CLOSE_ON_LOCK, &cinode->flags) &&
1092-
dclose && !(cfile->status_file_deleted)) {
1101+
if ((cfile->status_file_deleted == false) &&
1102+
(smb2_can_defer_close(inode, dclose))) {
10931103
if (test_and_clear_bit(CIFS_INO_MODIFIED_ATTR, &cinode->flags)) {
10941104
inode_set_mtime_to_ts(inode,
10951105
inode_set_ctime_current(inode));

fs/smb/client/inode.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,6 @@ cifs_get_file_info_unix(struct file *filp)
401401
cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);
402402
} else if (rc == -EREMOTE) {
403403
cifs_create_junction_fattr(&fattr, inode->i_sb);
404-
rc = 0;
405404
} else
406405
goto cifs_gfiunix_out;
407406

@@ -820,8 +819,10 @@ cifs_get_file_info(struct file *filp)
820819
void *page = alloc_dentry_path();
821820
const unsigned char *path;
822821

823-
if (!server->ops->query_file_info)
822+
if (!server->ops->query_file_info) {
823+
free_dentry_path(page);
824824
return -ENOSYS;
825+
}
825826

826827
xid = get_xid();
827828
rc = server->ops->query_file_info(xid, tcon, cfile, &data);
@@ -835,16 +836,15 @@ cifs_get_file_info(struct file *filp)
835836
}
836837
path = build_path_from_dentry(dentry, page);
837838
if (IS_ERR(path)) {
838-
free_dentry_path(page);
839-
return PTR_ERR(path);
839+
rc = PTR_ERR(path);
840+
goto cgfi_exit;
840841
}
841842
cifs_open_info_to_fattr(&fattr, &data, inode->i_sb);
842843
if (fattr.cf_flags & CIFS_FATTR_DELETE_PENDING)
843844
cifs_mark_open_handles_for_deleted_file(inode, path);
844845
break;
845846
case -EREMOTE:
846847
cifs_create_junction_fattr(&fattr, inode->i_sb);
847-
rc = 0;
848848
break;
849849
case -EOPNOTSUPP:
850850
case -EINVAL:
@@ -1009,7 +1009,6 @@ static int reparse_info_to_fattr(struct cifs_open_info_data *data,
10091009
struct kvec rsp_iov, *iov = NULL;
10101010
int rsp_buftype = CIFS_NO_BUFFER;
10111011
u32 tag = data->reparse.tag;
1012-
struct inode *inode = NULL;
10131012
int rc = 0;
10141013

10151014
if (!tag && server->ops->query_reparse_point) {
@@ -1049,12 +1048,8 @@ static int reparse_info_to_fattr(struct cifs_open_info_data *data,
10491048

10501049
if (tcon->posix_extensions)
10511050
smb311_posix_info_to_fattr(fattr, data, sb);
1052-
else {
1051+
else
10531052
cifs_open_info_to_fattr(fattr, data, sb);
1054-
inode = cifs_iget(sb, fattr);
1055-
if (inode && fattr->cf_flags & CIFS_FATTR_DELETE_PENDING)
1056-
cifs_mark_open_handles_for_deleted_file(inode, full_path);
1057-
}
10581053
out:
10591054
fattr->cf_cifstag = data->reparse.tag;
10601055
free_rsp_buf(rsp_buftype, rsp_iov.iov_base);
@@ -1109,9 +1104,9 @@ static int cifs_get_fattr(struct cifs_open_info_data *data,
11091104
full_path, fattr);
11101105
} else {
11111106
cifs_open_info_to_fattr(fattr, data, sb);
1112-
if (fattr->cf_flags & CIFS_FATTR_DELETE_PENDING)
1113-
cifs_mark_open_handles_for_deleted_file(*inode, full_path);
11141107
}
1108+
if (!rc && fattr->cf_flags & CIFS_FATTR_DELETE_PENDING)
1109+
cifs_mark_open_handles_for_deleted_file(*inode, full_path);
11151110
break;
11161111
case -EREMOTE:
11171112
/* DFS link, no metadata available on this server */
@@ -1340,6 +1335,8 @@ int smb311_posix_get_inode_info(struct inode **inode,
13401335
goto out;
13411336

13421337
rc = update_inode_info(sb, &fattr, inode);
1338+
if (!rc && fattr.cf_flags & CIFS_FATTR_DELETE_PENDING)
1339+
cifs_mark_open_handles_for_deleted_file(*inode, full_path);
13431340
out:
13441341
kfree(fattr.cf_symlink_target);
13451342
return rc;
@@ -1501,6 +1498,9 @@ struct inode *cifs_root_iget(struct super_block *sb)
15011498
goto out;
15021499
}
15031500

1501+
if (!rc && fattr.cf_flags & CIFS_FATTR_DELETE_PENDING)
1502+
cifs_mark_open_handles_for_deleted_file(inode, path);
1503+
15041504
if (rc && tcon->pipe) {
15051505
cifs_dbg(FYI, "ipc connection - fake read inode\n");
15061506
spin_lock(&inode->i_lock);

fs/smb/client/misc.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@
2727
#include "fs_context.h"
2828
#include "cached_dir.h"
2929

30-
extern mempool_t *cifs_sm_req_poolp;
31-
extern mempool_t *cifs_req_poolp;
32-
3330
/* The xid serves as a useful identifier for each incoming vfs request,
3431
in a similar way to the mid which is useful to track each sent smb,
3532
and CurrentXid can also provide a running counter (although it

fs/smb/client/sess.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ int cifs_try_adding_channels(struct cifs_ses *ses)
230230
spin_lock(&ses->iface_lock);
231231
if (!ses->iface_count) {
232232
spin_unlock(&ses->iface_lock);
233-
cifs_dbg(VFS, "server %s does not advertise interfaces\n",
233+
cifs_dbg(ONCE, "server %s does not advertise interfaces\n",
234234
ses->server->hostname);
235235
break;
236236
}
@@ -396,7 +396,7 @@ cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server)
396396
spin_lock(&ses->iface_lock);
397397
if (!ses->iface_count) {
398398
spin_unlock(&ses->iface_lock);
399-
cifs_dbg(VFS, "server %s does not advertise interfaces\n", ses->server->hostname);
399+
cifs_dbg(ONCE, "server %s does not advertise interfaces\n", ses->server->hostname);
400400
return;
401401
}
402402

fs/smb/client/smb2ops.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5290,6 +5290,7 @@ struct smb_version_operations smb30_operations = {
52905290
.tree_connect = SMB2_tcon,
52915291
.tree_disconnect = SMB2_tdis,
52925292
.qfs_tcon = smb3_qfs_tcon,
5293+
.query_server_interfaces = SMB3_request_interfaces,
52935294
.is_path_accessible = smb2_is_path_accessible,
52945295
.can_echo = smb2_can_echo,
52955296
.echo = SMB2_echo,
@@ -5405,6 +5406,7 @@ struct smb_version_operations smb311_operations = {
54055406
.tree_connect = SMB2_tcon,
54065407
.tree_disconnect = SMB2_tdis,
54075408
.qfs_tcon = smb3_qfs_tcon,
5409+
.query_server_interfaces = SMB3_request_interfaces,
54085410
.is_path_accessible = smb2_is_path_accessible,
54095411
.can_echo = smb2_can_echo,
54105412
.echo = SMB2_echo,

fs/smb/client/smb2pdu.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -409,14 +409,15 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
409409
spin_unlock(&ses->ses_lock);
410410

411411
if (!rc &&
412-
(server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)) {
412+
(server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL) &&
413+
server->ops->query_server_interfaces) {
413414
mutex_unlock(&ses->session_mutex);
414415

415416
/*
416417
* query server network interfaces, in case they change
417418
*/
418419
xid = get_xid();
419-
rc = SMB3_request_interfaces(xid, tcon, false);
420+
rc = server->ops->query_server_interfaces(xid, tcon, false);
420421
free_xid(xid);
421422

422423
if (rc == -EOPNOTSUPP && ses->chan_count > 1) {

0 commit comments

Comments
 (0)