mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-04-13 00:08:19 +07:00
cifs: add a helper to find an existing readable handle to a file
and convert smb2_query_path_info() to use it. This will eliminate the need for a SMB2_Create when we already have an open handle that can be used. This will also prevent a oplock break in case the other handle holds a lease. Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
563317ec30
commit
496902dc17
@ -140,6 +140,8 @@ extern int cifs_get_writable_file(struct cifsInodeInfo *cifs_inode,
|
|||||||
extern int cifs_get_writable_path(struct cifs_tcon *tcon, const char *name,
|
extern int cifs_get_writable_path(struct cifs_tcon *tcon, const char *name,
|
||||||
struct cifsFileInfo **ret_file);
|
struct cifsFileInfo **ret_file);
|
||||||
extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool);
|
extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool);
|
||||||
|
extern int cifs_get_readable_path(struct cifs_tcon *tcon, const char *name,
|
||||||
|
struct cifsFileInfo **ret_file);
|
||||||
extern unsigned int smbCalcSize(void *buf, struct TCP_Server_Info *server);
|
extern unsigned int smbCalcSize(void *buf, struct TCP_Server_Info *server);
|
||||||
extern int decode_negTokenInit(unsigned char *security_blob, int length,
|
extern int decode_negTokenInit(unsigned char *security_blob, int length,
|
||||||
struct TCP_Server_Info *server);
|
struct TCP_Server_Info *server);
|
||||||
|
@ -2008,6 +2008,42 @@ cifs_get_writable_path(struct cifs_tcon *tcon, const char *name,
|
|||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
cifs_get_readable_path(struct cifs_tcon *tcon, const char *name,
|
||||||
|
struct cifsFileInfo **ret_file)
|
||||||
|
{
|
||||||
|
struct list_head *tmp;
|
||||||
|
struct cifsFileInfo *cfile;
|
||||||
|
struct cifsInodeInfo *cinode;
|
||||||
|
char *full_path;
|
||||||
|
|
||||||
|
*ret_file = NULL;
|
||||||
|
|
||||||
|
spin_lock(&tcon->open_file_lock);
|
||||||
|
list_for_each(tmp, &tcon->openFileList) {
|
||||||
|
cfile = list_entry(tmp, struct cifsFileInfo,
|
||||||
|
tlist);
|
||||||
|
full_path = build_path_from_dentry(cfile->dentry);
|
||||||
|
if (full_path == NULL) {
|
||||||
|
spin_unlock(&tcon->open_file_lock);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
if (strcmp(full_path, name)) {
|
||||||
|
kfree(full_path);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
kfree(full_path);
|
||||||
|
cinode = CIFS_I(d_inode(cfile->dentry));
|
||||||
|
spin_unlock(&tcon->open_file_lock);
|
||||||
|
*ret_file = find_readable_file(cinode, 0);
|
||||||
|
return *ret_file ? 0 : -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_unlock(&tcon->open_file_lock);
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
|
static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
|
||||||
{
|
{
|
||||||
struct address_space *mapping = page->mapping;
|
struct address_space *mapping = page->mapping;
|
||||||
|
@ -125,15 +125,31 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
|
|||||||
rqst[num_rqst].rq_iov = qi_iov;
|
rqst[num_rqst].rq_iov = qi_iov;
|
||||||
rqst[num_rqst].rq_nvec = 1;
|
rqst[num_rqst].rq_nvec = 1;
|
||||||
|
|
||||||
rc = SMB2_query_info_init(tcon, &rqst[num_rqst], COMPOUND_FID,
|
if (cfile)
|
||||||
COMPOUND_FID, FILE_ALL_INFORMATION,
|
rc = SMB2_query_info_init(tcon, &rqst[num_rqst],
|
||||||
|
cfile->fid.persistent_fid,
|
||||||
|
cfile->fid.volatile_fid,
|
||||||
|
FILE_ALL_INFORMATION,
|
||||||
SMB2_O_INFO_FILE, 0,
|
SMB2_O_INFO_FILE, 0,
|
||||||
sizeof(struct smb2_file_all_info) +
|
sizeof(struct smb2_file_all_info) +
|
||||||
PATH_MAX * 2, 0, NULL);
|
PATH_MAX * 2, 0, NULL);
|
||||||
|
else {
|
||||||
|
rc = SMB2_query_info_init(tcon, &rqst[num_rqst],
|
||||||
|
COMPOUND_FID,
|
||||||
|
COMPOUND_FID,
|
||||||
|
FILE_ALL_INFORMATION,
|
||||||
|
SMB2_O_INFO_FILE, 0,
|
||||||
|
sizeof(struct smb2_file_all_info) +
|
||||||
|
PATH_MAX * 2, 0, NULL);
|
||||||
|
if (!rc) {
|
||||||
|
smb2_set_next_command(tcon, &rqst[num_rqst]);
|
||||||
|
smb2_set_related(&rqst[num_rqst]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (rc)
|
if (rc)
|
||||||
goto finished;
|
goto finished;
|
||||||
smb2_set_next_command(tcon, &rqst[num_rqst]);
|
num_rqst++;
|
||||||
smb2_set_related(&rqst[num_rqst++]);
|
|
||||||
trace_smb3_query_info_compound_enter(xid, ses->Suid, tcon->tid,
|
trace_smb3_query_info_compound_enter(xid, ses->Suid, tcon->tid,
|
||||||
full_path);
|
full_path);
|
||||||
break;
|
break;
|
||||||
@ -421,6 +437,7 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
|
|||||||
__u32 create_options = 0;
|
__u32 create_options = 0;
|
||||||
struct cifs_fid fid;
|
struct cifs_fid fid;
|
||||||
bool no_cached_open = tcon->nohandlecache;
|
bool no_cached_open = tcon->nohandlecache;
|
||||||
|
struct cifsFileInfo *cfile;
|
||||||
|
|
||||||
*adjust_tz = false;
|
*adjust_tz = false;
|
||||||
*symlink = false;
|
*symlink = false;
|
||||||
@ -452,9 +469,10 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
|
|||||||
if (backup_cred(cifs_sb))
|
if (backup_cred(cifs_sb))
|
||||||
create_options |= CREATE_OPEN_BACKUP_INTENT;
|
create_options |= CREATE_OPEN_BACKUP_INTENT;
|
||||||
|
|
||||||
|
cifs_get_readable_path(tcon, full_path, &cfile);
|
||||||
rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
|
rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
|
||||||
FILE_READ_ATTRIBUTES, FILE_OPEN, create_options,
|
FILE_READ_ATTRIBUTES, FILE_OPEN, create_options,
|
||||||
smb2_data, SMB2_OP_QUERY_INFO, NULL);
|
smb2_data, SMB2_OP_QUERY_INFO, cfile);
|
||||||
if (rc == -EOPNOTSUPP) {
|
if (rc == -EOPNOTSUPP) {
|
||||||
*symlink = true;
|
*symlink = true;
|
||||||
create_options |= OPEN_REPARSE_POINT;
|
create_options |= OPEN_REPARSE_POINT;
|
||||||
|
Loading…
Reference in New Issue
Block a user