diff options
| author | Enzo Matsumiya <ematsumiya@suse.de> | 2025-09-08 18:12:40 -0300 |
|---|---|---|
| committer | Enzo Matsumiya <ematsumiya@suse.de> | 2025-10-07 10:59:13 -0300 |
| commit | 554df0fec90f4ad4ad48c0b42506ef570b763164 (patch) | |
| tree | f7a7830593cb676ea04e947e935ce99dee157d46 | |
| parent | ad5c089300cdea282c68f2d29e98815709bf39aa (diff) | |
| download | linux-554df0fec90f4ad4ad48c0b42506ef570b763164.tar.gz linux-554df0fec90f4ad4ad48c0b42506ef570b763164.tar.bz2 linux-554df0fec90f4ad4ad48c0b42506ef570b763164.zip | |
smb: client: use cached dir on queryfs/smb2_compound_op
A dentry is passed to cifs_statfs(), so pass down d_is_dir() to
smb2_queryfs() so we can cache/reuse this dir.
Other:
- make smb2_compound_op a static function, as it's not used anywhere
else
Signed-off-by: Enzo Matsumiya <ematsumiya@suse.de>
| -rw-r--r-- | fs/smb/client/cifsfs.c | 2 | ||||
| -rw-r--r-- | fs/smb/client/cifsglob.h | 2 | ||||
| -rw-r--r-- | fs/smb/client/smb1ops.c | 2 | ||||
| -rw-r--r-- | fs/smb/client/smb2ops.c | 32 | ||||
| -rw-r--r-- | fs/smb/client/smb2proto.h | 6 |
5 files changed, 20 insertions, 24 deletions
diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c index 54a19bfc6170..c961547be0ed 100644 --- a/fs/smb/client/cifsfs.c +++ b/fs/smb/client/cifsfs.c @@ -379,7 +379,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf) buf->f_ffree = 0; /* unlimited */ if (server->ops->queryfs) - rc = server->ops->queryfs(xid, tcon, full_path, cifs_sb, buf); + rc = server->ops->queryfs(xid, tcon, full_path, cifs_sb, buf, d_is_dir(dentry)); statfs_out: free_dentry_path(page); diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index 207221eae5f6..85605490078b 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -519,7 +519,7 @@ struct smb_version_operations { __u16 net_fid, struct cifsInodeInfo *cifs_inode); /* query remote filesystem */ int (*queryfs)(const unsigned int, struct cifs_tcon *, - const char *, struct cifs_sb_info *, struct kstatfs *); + const char *, struct cifs_sb_info *, struct kstatfs *, bool); /* send mandatory brlock to the server */ int (*mand_lock)(const unsigned int, struct cifsFileInfo *, __u64, __u64, __u32, int, int, bool); diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c index d964bc9c2823..9fa1ff9ea70d 100644 --- a/fs/smb/client/smb1ops.c +++ b/fs/smb/client/smb1ops.c @@ -1105,7 +1105,7 @@ cifs_oplock_response(struct cifs_tcon *tcon, __u64 persistent_fid, static int cifs_queryfs(const unsigned int xid, struct cifs_tcon *tcon, - const char *path, struct cifs_sb_info *cifs_sb, struct kstatfs *buf) + const char *path, struct cifs_sb_info *cifs_sb, struct kstatfs *buf, bool is_dir) { int rc = -EOPNOTSUPP; diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index cc2c1f9b76f2..1116ae8f989a 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -1110,6 +1110,11 @@ out: return (ssize_t)rc; } +static int smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, + const char *path, u32 desired_access, u32 class, u32 type, + u32 output_len, struct kvec *rsp, int *buftype, + struct cifs_sb_info *cifs_sb, bool is_dir); + static ssize_t smb2_query_eas(const unsigned int xid, struct cifs_tcon *tcon, const unsigned char *path, const unsigned char *ea_name, @@ -1129,7 +1134,7 @@ smb2_query_eas(const unsigned int xid, struct cifs_tcon *tcon, CIFSMaxBufSize - MAX_SMB2_CREATE_RESPONSE_SIZE - MAX_SMB2_CLOSE_RESPONSE_SIZE, - &rsp_iov, &buftype, cifs_sb); + &rsp_iov, &buftype, cifs_sb, false); if (rc) { /* * If ea_name is NULL (listxattr) and there are no EAs, @@ -1231,7 +1236,7 @@ replay_again: CIFSMaxBufSize - MAX_SMB2_CREATE_RESPONSE_SIZE - MAX_SMB2_CLOSE_RESPONSE_SIZE, - &rsp_iov[1], &resp_buftype[1], cifs_sb); + &rsp_iov[1], &resp_buftype[1], cifs_sb, false); if (rc == 0) { rsp = (struct smb2_query_info_rsp *)rsp_iov[1].iov_base; used_len = le32_to_cpu(rsp->OutputBufferLength); @@ -2694,12 +2699,10 @@ bool smb2_should_replay(struct cifs_tcon *tcon, * Passes the query info response back to the caller on success. * Caller need to free this with free_rsp_buf(). */ -int -smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, - const char *path, u32 desired_access, - u32 class, u32 type, u32 output_len, - struct kvec *rsp, int *buftype, - struct cifs_sb_info *cifs_sb) +static int smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, + const char *path, u32 desired_access, u32 class, u32 type, + u32 output_len, struct kvec *rsp, int *buftype, + struct cifs_sb_info *cifs_sb, bool is_dir) { struct smb2_compound_vars *vars; struct cifs_ses *ses = tcon->ses; @@ -2741,9 +2744,9 @@ replay_again: rsp_iov = vars->rsp_iov; /* - * We can only call this for things we know are directories. + * We can only open + cache paths we know are directories. */ - if (!strcmp(path, "")) + if (is_dir) /* cfid null if open dir failed */ open_cached_dir(xid, tcon, path, cifs_sb, &cfid); @@ -2852,7 +2855,7 @@ out_free_path: static int smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon, - const char *path, struct cifs_sb_info *cifs_sb, struct kstatfs *buf) + const char *path, struct cifs_sb_info *cifs_sb, struct kstatfs *buf, bool is_dir) { struct smb2_query_info_rsp *rsp; struct smb2_fs_full_size_info *info = NULL; @@ -2860,13 +2863,12 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon, int buftype = CIFS_NO_BUFFER; int rc; - rc = smb2_query_info_compound(xid, tcon, path, FILE_READ_ATTRIBUTES, FS_FULL_SIZE_INFORMATION, SMB2_O_INFO_FILESYSTEM, sizeof(struct smb2_fs_full_size_info), - &rsp_iov, &buftype, cifs_sb); + &rsp_iov, &buftype, cifs_sb, is_dir); if (rc) goto qfs_exit; @@ -2889,7 +2891,7 @@ qfs_exit: static int smb311_queryfs(const unsigned int xid, struct cifs_tcon *tcon, - const char *path, struct cifs_sb_info *cifs_sb, struct kstatfs *buf) + const char *path, struct cifs_sb_info *cifs_sb, struct kstatfs *buf, bool is_dir) { int rc; __le16 *utf16_path = NULL; @@ -2898,7 +2900,7 @@ smb311_queryfs(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_fid fid; if (!tcon->posix_extensions) - return smb2_queryfs(xid, tcon, path, cifs_sb, buf); + return smb2_queryfs(xid, tcon, path, cifs_sb, buf, is_dir); oparms = (struct cifs_open_parms) { .tcon = tcon, diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h index 3e3faa7cf633..99326810a159 100644 --- a/fs/smb/client/smb2proto.h +++ b/fs/smb/client/smb2proto.h @@ -299,12 +299,6 @@ extern int smb311_crypto_shash_allocate(struct TCP_Server_Info *server); extern int smb311_update_preauth_hash(struct cifs_ses *ses, struct TCP_Server_Info *server, struct kvec *iov, int nvec); -extern int smb2_query_info_compound(const unsigned int xid, - struct cifs_tcon *tcon, - const char *path, u32 desired_access, - u32 class, u32 type, u32 output_len, - struct kvec *rsp, int *buftype, - struct cifs_sb_info *cifs_sb); /* query path info from the server using SMB311 POSIX extensions*/ int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, |
