Commit 92fc65a7 authored by Pavel Shilovsky's avatar Pavel Shilovsky Committed by Steve French

CIFS: Move readdir code to ops struct

Signed-off-by: default avatarPavel Shilovsky <pshilovsky@samba.org>
Signed-off-by: default avatarSteve French <smfrench@gmail.com>
parent 1feeaac7
...@@ -177,6 +177,7 @@ struct cifs_fid; ...@@ -177,6 +177,7 @@ struct cifs_fid;
struct cifs_readdata; struct cifs_readdata;
struct cifs_writedata; struct cifs_writedata;
struct cifs_io_parms; struct cifs_io_parms;
struct cifs_search_info;
struct smb_version_operations { struct smb_version_operations {
int (*send_cancel)(struct TCP_Server_Info *, void *, int (*send_cancel)(struct TCP_Server_Info *, void *,
...@@ -313,6 +314,20 @@ struct smb_version_operations { ...@@ -313,6 +314,20 @@ struct smb_version_operations {
int (*sync_write)(const unsigned int, struct cifsFileInfo *, int (*sync_write)(const unsigned int, struct cifsFileInfo *,
struct cifs_io_parms *, unsigned int *, struct kvec *, struct cifs_io_parms *, unsigned int *, struct kvec *,
unsigned long); unsigned long);
/* open dir, start readdir */
int (*query_dir_first)(const unsigned int, struct cifs_tcon *,
const char *, struct cifs_sb_info *,
struct cifs_fid *, __u16,
struct cifs_search_info *);
/* continue readdir */
int (*query_dir_next)(const unsigned int, struct cifs_tcon *,
struct cifs_fid *,
__u16, struct cifs_search_info *srch_inf);
/* close dir */
int (*close_dir)(const unsigned int, struct cifs_tcon *,
struct cifs_fid *);
/* calculate a size of SMB message */
unsigned int (*calc_smb_size)(void *);
}; };
struct smb_version_values { struct smb_version_values {
......
...@@ -100,7 +100,7 @@ extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset, ...@@ -100,7 +100,7 @@ extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
unsigned int bytes_written); unsigned int bytes_written);
extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool); extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool);
extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool); extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool);
extern unsigned int smbCalcSize(struct smb_hdr *ptr); extern unsigned int smbCalcSize(void *buf);
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);
extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len); extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len);
......
...@@ -618,39 +618,47 @@ int cifs_closedir(struct inode *inode, struct file *file) ...@@ -618,39 +618,47 @@ int cifs_closedir(struct inode *inode, struct file *file)
int rc = 0; int rc = 0;
unsigned int xid; unsigned int xid;
struct cifsFileInfo *cfile = file->private_data; struct cifsFileInfo *cfile = file->private_data;
char *tmp; struct cifs_tcon *tcon;
struct TCP_Server_Info *server;
char *buf;
cFYI(1, "Closedir inode = 0x%p", inode); cFYI(1, "Closedir inode = 0x%p", inode);
xid = get_xid(); if (cfile == NULL)
return rc;
if (cfile) { xid = get_xid();
struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); tcon = tlink_tcon(cfile->tlink);
server = tcon->ses->server;
cFYI(1, "Freeing private data in close dir"); cFYI(1, "Freeing private data in close dir");
spin_lock(&cifs_file_list_lock); spin_lock(&cifs_file_list_lock);
if (!cfile->srch_inf.endOfSearch && !cfile->invalidHandle) { if (!cfile->srch_inf.endOfSearch && !cfile->invalidHandle) {
cfile->invalidHandle = true; cfile->invalidHandle = true;
spin_unlock(&cifs_file_list_lock); spin_unlock(&cifs_file_list_lock);
rc = CIFSFindClose(xid, tcon, cfile->fid.netfid); if (server->ops->close_dir)
rc = server->ops->close_dir(xid, tcon, &cfile->fid);
else
rc = -ENOSYS;
cFYI(1, "Closing uncompleted readdir with rc %d", rc); cFYI(1, "Closing uncompleted readdir with rc %d", rc);
/* not much we can do if it fails anyway, ignore rc */ /* not much we can do if it fails anyway, ignore rc */
rc = 0; rc = 0;
} else } else
spin_unlock(&cifs_file_list_lock); spin_unlock(&cifs_file_list_lock);
tmp = cfile->srch_inf.ntwrk_buf_start;
if (tmp) { buf = cfile->srch_inf.ntwrk_buf_start;
if (buf) {
cFYI(1, "closedir free smb buf in srch struct"); cFYI(1, "closedir free smb buf in srch struct");
cfile->srch_inf.ntwrk_buf_start = NULL; cfile->srch_inf.ntwrk_buf_start = NULL;
if (cfile->srch_inf.smallBuf) if (cfile->srch_inf.smallBuf)
cifs_small_buf_release(tmp); cifs_small_buf_release(buf);
else else
cifs_buf_release(tmp); cifs_buf_release(buf);
} }
cifs_put_tlink(cfile->tlink); cifs_put_tlink(cfile->tlink);
kfree(file->private_data); kfree(file->private_data);
file->private_data = NULL; file->private_data = NULL;
}
/* BB can we lock the filestruct while this is going on? */ /* BB can we lock the filestruct while this is going on? */
free_xid(xid); free_xid(xid);
return rc; return rc;
......
...@@ -913,8 +913,9 @@ map_smb_to_linux_error(char *buf, bool logErr) ...@@ -913,8 +913,9 @@ map_smb_to_linux_error(char *buf, bool logErr)
* portion, the number of word parameters and the data portion of the message * portion, the number of word parameters and the data portion of the message
*/ */
unsigned int unsigned int
smbCalcSize(struct smb_hdr *ptr) smbCalcSize(void *buf)
{ {
struct smb_hdr *ptr = (struct smb_hdr *)buf;
return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) + return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) +
2 /* size of the bcc field */ + get_bcc(ptr)); 2 /* size of the bcc field */ + get_bcc(ptr));
} }
......
This diff is collapsed.
...@@ -836,6 +836,33 @@ smb_set_file_info(struct inode *inode, const char *full_path, ...@@ -836,6 +836,33 @@ smb_set_file_info(struct inode *inode, const char *full_path,
return rc; return rc;
} }
static int
cifs_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
const char *path, struct cifs_sb_info *cifs_sb,
struct cifs_fid *fid, __u16 search_flags,
struct cifs_search_info *srch_inf)
{
return CIFSFindFirst(xid, tcon, path, cifs_sb->local_nls,
&fid->netfid, search_flags, srch_inf,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb));
}
static int
cifs_query_dir_next(const unsigned int xid, struct cifs_tcon *tcon,
struct cifs_fid *fid, __u16 search_flags,
struct cifs_search_info *srch_inf)
{
return CIFSFindNext(xid, tcon, fid->netfid, search_flags, srch_inf);
}
static int
cifs_close_dir(const unsigned int xid, struct cifs_tcon *tcon,
struct cifs_fid *fid)
{
return CIFSFindClose(xid, tcon, fid->netfid);
}
struct smb_version_operations smb1_operations = { struct smb_version_operations smb1_operations = {
.send_cancel = send_nt_cancel, .send_cancel = send_nt_cancel,
.compare_fids = cifs_compare_fids, .compare_fids = cifs_compare_fids,
...@@ -891,6 +918,10 @@ struct smb_version_operations smb1_operations = { ...@@ -891,6 +918,10 @@ struct smb_version_operations smb1_operations = {
.async_writev = cifs_async_writev, .async_writev = cifs_async_writev,
.sync_read = cifs_sync_read, .sync_read = cifs_sync_read,
.sync_write = cifs_sync_write, .sync_write = cifs_sync_write,
.query_dir_first = cifs_query_dir_first,
.query_dir_next = cifs_query_dir_next,
.close_dir = cifs_close_dir,
.calc_smb_size = smbCalcSize,
}; };
struct smb_version_values smb1_values = { struct smb_version_values smb1_values = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment