forked from luck/tmp_suning_uos_patched
Merge master.kernel.org:/pub/scm/linux/kernel/git/sfrench/cifs-2.6-stable
* master.kernel.org:/pub/scm/linux/kernel/git/sfrench/cifs-2.6-stable: [CIFS] Fix typo in previous [CIFS] Readdir fixes to allow search to start at arbitrary position [CIFS] Use the kthread_ API instead of opencoding lots of hairy code for kernel [CIFS] Don't allow a backslash in a path component [CIFS] [CIFS] Do not take rename sem on most path based calls (during
This commit is contained in:
commit
41bc3982b9
@ -1,7 +1,11 @@
|
|||||||
Version 1.42
|
Version 1.42
|
||||||
------------
|
------------
|
||||||
Fix slow oplock break when mounted to different servers at the same time and
|
Fix slow oplock break when mounted to different servers at the same time and
|
||||||
the tids match and we try to find matching fid on wrong server.
|
the tids match and we try to find matching fid on wrong server. Fix read
|
||||||
|
looping when signing required by server (2.6.16 kernel only). Fix readdir
|
||||||
|
vs. rename race which could cause each to hang. Return . and .. even
|
||||||
|
if server does not. Allow searches to skip first three entries and
|
||||||
|
begin at any location. Fix oops in find_writeable_file.
|
||||||
|
|
||||||
Version 1.41
|
Version 1.41
|
||||||
------------
|
------------
|
||||||
|
@ -511,6 +511,14 @@ LinuxExtensionsEnabled If set to one then the client will attempt to
|
|||||||
support and want to map the uid and gid fields
|
support and want to map the uid and gid fields
|
||||||
to values supplied at mount (rather than the
|
to values supplied at mount (rather than the
|
||||||
actual values, then set this to zero. (default 1)
|
actual values, then set this to zero. (default 1)
|
||||||
|
Experimental When set to 1 used to enable certain experimental
|
||||||
|
features (currently enables multipage writes
|
||||||
|
when signing is enabled, the multipage write
|
||||||
|
performance enhancement was disabled when
|
||||||
|
signing turned on in case buffer was modified
|
||||||
|
just before it was sent, also this flag will
|
||||||
|
be used to use the new experimental sessionsetup
|
||||||
|
code).
|
||||||
|
|
||||||
These experimental features and tracing can be enabled by changing flags in
|
These experimental features and tracing can be enabled by changing flags in
|
||||||
/proc/fs/cifs (after the cifs module has been installed or built into the
|
/proc/fs/cifs (after the cifs module has been installed or built into the
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include <linux/vfs.h>
|
#include <linux/vfs.h>
|
||||||
#include <linux/mempool.h>
|
#include <linux/mempool.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
#include <linux/kthread.h>
|
||||||
#include "cifsfs.h"
|
#include "cifsfs.h"
|
||||||
#include "cifspdu.h"
|
#include "cifspdu.h"
|
||||||
#define DECLARE_GLOBALS_HERE
|
#define DECLARE_GLOBALS_HERE
|
||||||
@ -75,9 +76,6 @@ unsigned int cifs_max_pending = CIFS_MAX_REQ;
|
|||||||
module_param(cifs_max_pending, int, 0);
|
module_param(cifs_max_pending, int, 0);
|
||||||
MODULE_PARM_DESC(cifs_max_pending,"Simultaneous requests to server. Default: 50 Range: 2 to 256");
|
MODULE_PARM_DESC(cifs_max_pending,"Simultaneous requests to server. Default: 50 Range: 2 to 256");
|
||||||
|
|
||||||
static DECLARE_COMPLETION(cifs_oplock_exited);
|
|
||||||
static DECLARE_COMPLETION(cifs_dnotify_exited);
|
|
||||||
|
|
||||||
extern mempool_t *cifs_sm_req_poolp;
|
extern mempool_t *cifs_sm_req_poolp;
|
||||||
extern mempool_t *cifs_req_poolp;
|
extern mempool_t *cifs_req_poolp;
|
||||||
extern mempool_t *cifs_mid_poolp;
|
extern mempool_t *cifs_mid_poolp;
|
||||||
@ -841,10 +839,6 @@ static int cifs_oplock_thread(void * dummyarg)
|
|||||||
__u16 netfid;
|
__u16 netfid;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
daemonize("cifsoplockd");
|
|
||||||
allow_signal(SIGTERM);
|
|
||||||
|
|
||||||
oplockThread = current;
|
|
||||||
do {
|
do {
|
||||||
if (try_to_freeze())
|
if (try_to_freeze())
|
||||||
continue;
|
continue;
|
||||||
@ -900,9 +894,9 @@ static int cifs_oplock_thread(void * dummyarg)
|
|||||||
set_current_state(TASK_INTERRUPTIBLE);
|
set_current_state(TASK_INTERRUPTIBLE);
|
||||||
schedule_timeout(1); /* yield in case q were corrupt */
|
schedule_timeout(1); /* yield in case q were corrupt */
|
||||||
}
|
}
|
||||||
} while(!signal_pending(current));
|
} while (!kthread_should_stop());
|
||||||
oplockThread = NULL;
|
|
||||||
complete_and_exit (&cifs_oplock_exited, 0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cifs_dnotify_thread(void * dummyarg)
|
static int cifs_dnotify_thread(void * dummyarg)
|
||||||
@ -910,10 +904,6 @@ static int cifs_dnotify_thread(void * dummyarg)
|
|||||||
struct list_head *tmp;
|
struct list_head *tmp;
|
||||||
struct cifsSesInfo *ses;
|
struct cifsSesInfo *ses;
|
||||||
|
|
||||||
daemonize("cifsdnotifyd");
|
|
||||||
allow_signal(SIGTERM);
|
|
||||||
|
|
||||||
dnotifyThread = current;
|
|
||||||
do {
|
do {
|
||||||
if(try_to_freeze())
|
if(try_to_freeze())
|
||||||
continue;
|
continue;
|
||||||
@ -931,8 +921,9 @@ static int cifs_dnotify_thread(void * dummyarg)
|
|||||||
wake_up_all(&ses->server->response_q);
|
wake_up_all(&ses->server->response_q);
|
||||||
}
|
}
|
||||||
read_unlock(&GlobalSMBSeslock);
|
read_unlock(&GlobalSMBSeslock);
|
||||||
} while(!signal_pending(current));
|
} while (!kthread_should_stop());
|
||||||
complete_and_exit (&cifs_dnotify_exited, 0);
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init
|
static int __init
|
||||||
@ -982,32 +973,48 @@ init_cifs(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
rc = cifs_init_inodecache();
|
rc = cifs_init_inodecache();
|
||||||
if (!rc) {
|
if (rc)
|
||||||
rc = cifs_init_mids();
|
goto out_clean_proc;
|
||||||
if (!rc) {
|
|
||||||
rc = cifs_init_request_bufs();
|
rc = cifs_init_mids();
|
||||||
if (!rc) {
|
if (rc)
|
||||||
rc = register_filesystem(&cifs_fs_type);
|
goto out_destroy_inodecache;
|
||||||
if (!rc) {
|
|
||||||
rc = (int)kernel_thread(cifs_oplock_thread, NULL,
|
rc = cifs_init_request_bufs();
|
||||||
CLONE_FS | CLONE_FILES | CLONE_VM);
|
if (rc)
|
||||||
if(rc > 0) {
|
goto out_destroy_mids;
|
||||||
rc = (int)kernel_thread(cifs_dnotify_thread, NULL,
|
|
||||||
CLONE_FS | CLONE_FILES | CLONE_VM);
|
rc = register_filesystem(&cifs_fs_type);
|
||||||
if(rc > 0)
|
if (rc)
|
||||||
return 0;
|
goto out_destroy_request_bufs;
|
||||||
else
|
|
||||||
cERROR(1,("error %d create dnotify thread", rc));
|
oplockThread = kthread_run(cifs_oplock_thread, NULL, "cifsoplockd");
|
||||||
} else {
|
if (IS_ERR(oplockThread)) {
|
||||||
cERROR(1,("error %d create oplock thread",rc));
|
rc = PTR_ERR(oplockThread);
|
||||||
}
|
cERROR(1,("error %d create oplock thread", rc));
|
||||||
}
|
goto out_unregister_filesystem;
|
||||||
cifs_destroy_request_bufs();
|
|
||||||
}
|
|
||||||
cifs_destroy_mids();
|
|
||||||
}
|
|
||||||
cifs_destroy_inodecache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dnotifyThread = kthread_run(cifs_dnotify_thread, NULL, "cifsdnotifyd");
|
||||||
|
if (IS_ERR(dnotifyThread)) {
|
||||||
|
rc = PTR_ERR(dnotifyThread);
|
||||||
|
cERROR(1,("error %d create dnotify thread", rc));
|
||||||
|
goto out_stop_oplock_thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
out_stop_oplock_thread:
|
||||||
|
kthread_stop(oplockThread);
|
||||||
|
out_unregister_filesystem:
|
||||||
|
unregister_filesystem(&cifs_fs_type);
|
||||||
|
out_destroy_request_bufs:
|
||||||
|
cifs_destroy_request_bufs();
|
||||||
|
out_destroy_mids:
|
||||||
|
cifs_destroy_mids();
|
||||||
|
out_destroy_inodecache:
|
||||||
|
cifs_destroy_inodecache();
|
||||||
|
out_clean_proc:
|
||||||
#ifdef CONFIG_PROC_FS
|
#ifdef CONFIG_PROC_FS
|
||||||
cifs_proc_clean();
|
cifs_proc_clean();
|
||||||
#endif
|
#endif
|
||||||
@ -1025,14 +1032,8 @@ exit_cifs(void)
|
|||||||
cifs_destroy_inodecache();
|
cifs_destroy_inodecache();
|
||||||
cifs_destroy_mids();
|
cifs_destroy_mids();
|
||||||
cifs_destroy_request_bufs();
|
cifs_destroy_request_bufs();
|
||||||
if(oplockThread) {
|
kthread_stop(oplockThread);
|
||||||
send_sig(SIGTERM, oplockThread, 1);
|
kthread_stop(dnotifyThread);
|
||||||
wait_for_completion(&cifs_oplock_exited);
|
|
||||||
}
|
|
||||||
if(dnotifyThread) {
|
|
||||||
send_sig(SIGTERM, dnotifyThread, 1);
|
|
||||||
wait_for_completion(&cifs_dnotify_exited);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>");
|
MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>");
|
||||||
|
@ -3119,7 +3119,7 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
|
|||||||
psrch_inf->endOfSearch = FALSE;
|
psrch_inf->endOfSearch = FALSE;
|
||||||
|
|
||||||
psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount);
|
psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount);
|
||||||
psrch_inf->index_of_last_entry =
|
psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
|
||||||
psrch_inf->entries_in_buffer;
|
psrch_inf->entries_in_buffer;
|
||||||
*pnetfid = parms->SearchHandle;
|
*pnetfid = parms->SearchHandle;
|
||||||
} else {
|
} else {
|
||||||
|
@ -3447,7 +3447,10 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
|
|||||||
pSesInfo->server->secMode,
|
pSesInfo->server->secMode,
|
||||||
pSesInfo->server->capabilities,
|
pSesInfo->server->capabilities,
|
||||||
pSesInfo->server->timeZone));
|
pSesInfo->server->timeZone));
|
||||||
if (extended_security
|
if(experimEnabled > 1)
|
||||||
|
rc = CIFS_SessSetup(xid, pSesInfo, CIFS_NTLM /* type */,
|
||||||
|
&ntlmv2_flag, nls_info);
|
||||||
|
else if (extended_security
|
||||||
&& (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
|
&& (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
|
||||||
&& (pSesInfo->server->secType == NTLMSSP)) {
|
&& (pSesInfo->server->secType == NTLMSSP)) {
|
||||||
cFYI(1, ("New style sesssetup"));
|
cFYI(1, ("New style sesssetup"));
|
||||||
|
@ -139,9 +139,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
|
|||||||
cifs_sb = CIFS_SB(inode->i_sb);
|
cifs_sb = CIFS_SB(inode->i_sb);
|
||||||
pTcon = cifs_sb->tcon;
|
pTcon = cifs_sb->tcon;
|
||||||
|
|
||||||
mutex_lock(&direntry->d_sb->s_vfs_rename_mutex);
|
|
||||||
full_path = build_path_from_dentry(direntry);
|
full_path = build_path_from_dentry(direntry);
|
||||||
mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex);
|
|
||||||
if(full_path == NULL) {
|
if(full_path == NULL) {
|
||||||
FreeXid(xid);
|
FreeXid(xid);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -316,9 +314,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
|
|||||||
cifs_sb = CIFS_SB(inode->i_sb);
|
cifs_sb = CIFS_SB(inode->i_sb);
|
||||||
pTcon = cifs_sb->tcon;
|
pTcon = cifs_sb->tcon;
|
||||||
|
|
||||||
mutex_lock(&direntry->d_sb->s_vfs_rename_mutex);
|
|
||||||
full_path = build_path_from_dentry(direntry);
|
full_path = build_path_from_dentry(direntry);
|
||||||
mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex);
|
|
||||||
if(full_path == NULL)
|
if(full_path == NULL)
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
else if (pTcon->ses->capabilities & CAP_UNIX) {
|
else if (pTcon->ses->capabilities & CAP_UNIX) {
|
||||||
@ -440,6 +436,20 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
|
|||||||
cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
|
cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
|
||||||
pTcon = cifs_sb->tcon;
|
pTcon = cifs_sb->tcon;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Don't allow the separator character in a path component.
|
||||||
|
* The VFS will not allow "/", but "\" is allowed by posix.
|
||||||
|
*/
|
||||||
|
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < direntry->d_name.len; i++)
|
||||||
|
if (direntry->d_name.name[i] == '\\') {
|
||||||
|
cFYI(1, ("Invalid file name"));
|
||||||
|
FreeXid(xid);
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* can not grab the rename sem here since it would
|
/* can not grab the rename sem here since it would
|
||||||
deadlock in the cases (beginning of sys_rename itself)
|
deadlock in the cases (beginning of sys_rename itself)
|
||||||
in which we already have the sb rename sem */
|
in which we already have the sb rename sem */
|
||||||
|
@ -86,9 +86,7 @@ int cifs_dir_notify(struct file * file, unsigned long arg)
|
|||||||
cifs_sb = CIFS_SB(file->f_dentry->d_sb);
|
cifs_sb = CIFS_SB(file->f_dentry->d_sb);
|
||||||
pTcon = cifs_sb->tcon;
|
pTcon = cifs_sb->tcon;
|
||||||
|
|
||||||
mutex_lock(&file->f_dentry->d_sb->s_vfs_rename_mutex);
|
|
||||||
full_path = build_path_from_dentry(file->f_dentry);
|
full_path = build_path_from_dentry(file->f_dentry);
|
||||||
mutex_unlock(&file->f_dentry->d_sb->s_vfs_rename_mutex);
|
|
||||||
|
|
||||||
if(full_path == NULL) {
|
if(full_path == NULL) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
|
@ -203,9 +203,7 @@ int cifs_open(struct inode *inode, struct file *file)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&inode->i_sb->s_vfs_rename_mutex);
|
|
||||||
full_path = build_path_from_dentry(file->f_dentry);
|
full_path = build_path_from_dentry(file->f_dentry);
|
||||||
mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);
|
|
||||||
if (full_path == NULL) {
|
if (full_path == NULL) {
|
||||||
FreeXid(xid);
|
FreeXid(xid);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -906,8 +904,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
|
|||||||
if (rc != 0)
|
if (rc != 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* BB FIXME We can not sign across two buffers yet */
|
if(experimEnabled || (pTcon->ses->server->secMode &
|
||||||
if((pTcon->ses->server->secMode &
|
|
||||||
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0) {
|
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0) {
|
||||||
struct kvec iov[2];
|
struct kvec iov[2];
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
@ -923,13 +920,13 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
|
|||||||
*poffset, &bytes_written,
|
*poffset, &bytes_written,
|
||||||
iov, 1, long_op);
|
iov, 1, long_op);
|
||||||
} else
|
} else
|
||||||
/* BB FIXME fixup indentation of line below */
|
rc = CIFSSMBWrite(xid, pTcon,
|
||||||
rc = CIFSSMBWrite(xid, pTcon,
|
open_file->netfid,
|
||||||
open_file->netfid,
|
min_t(const int, cifs_sb->wsize,
|
||||||
min_t(const int, cifs_sb->wsize,
|
write_size - total_written),
|
||||||
write_size - total_written),
|
*poffset, &bytes_written,
|
||||||
*poffset, &bytes_written,
|
write_data + total_written,
|
||||||
write_data + total_written, NULL, long_op);
|
NULL, long_op);
|
||||||
}
|
}
|
||||||
if (rc || (bytes_written == 0)) {
|
if (rc || (bytes_written == 0)) {
|
||||||
if (total_written)
|
if (total_written)
|
||||||
@ -968,6 +965,16 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
|
|||||||
struct cifsFileInfo *open_file;
|
struct cifsFileInfo *open_file;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
/* Having a null inode here (because mapping->host was set to zero by
|
||||||
|
the VFS or MM) should not happen but we had reports of on oops (due to
|
||||||
|
it being zero) during stress testcases so we need to check for it */
|
||||||
|
|
||||||
|
if(cifs_inode == NULL) {
|
||||||
|
cERROR(1,("Null inode passed to cifs_writeable_file"));
|
||||||
|
dump_stack();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
read_lock(&GlobalSMBSeslock);
|
read_lock(&GlobalSMBSeslock);
|
||||||
list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
|
list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
|
||||||
if (open_file->closePend)
|
if (open_file->closePend)
|
||||||
@ -1093,12 +1100,11 @@ static int cifs_writepages(struct address_space *mapping,
|
|||||||
if (cifs_sb->wsize < PAGE_CACHE_SIZE)
|
if (cifs_sb->wsize < PAGE_CACHE_SIZE)
|
||||||
return generic_writepages(mapping, wbc);
|
return generic_writepages(mapping, wbc);
|
||||||
|
|
||||||
/* BB FIXME we do not have code to sign across multiple buffers yet,
|
|
||||||
so go to older writepage style write which we can sign if needed */
|
|
||||||
if((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->server))
|
if((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->server))
|
||||||
if(cifs_sb->tcon->ses->server->secMode &
|
if(cifs_sb->tcon->ses->server->secMode &
|
||||||
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
|
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
|
||||||
return generic_writepages(mapping, wbc);
|
if(!experimEnabled)
|
||||||
|
return generic_writepages(mapping, wbc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BB: Is this meaningful for a non-block-device file system?
|
* BB: Is this meaningful for a non-block-device file system?
|
||||||
|
@ -722,9 +722,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
|
|||||||
cifs_sb = CIFS_SB(inode->i_sb);
|
cifs_sb = CIFS_SB(inode->i_sb);
|
||||||
pTcon = cifs_sb->tcon;
|
pTcon = cifs_sb->tcon;
|
||||||
|
|
||||||
mutex_lock(&inode->i_sb->s_vfs_rename_mutex);
|
|
||||||
full_path = build_path_from_dentry(direntry);
|
full_path = build_path_from_dentry(direntry);
|
||||||
mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);
|
|
||||||
if (full_path == NULL) {
|
if (full_path == NULL) {
|
||||||
FreeXid(xid);
|
FreeXid(xid);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -807,9 +805,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
|
|||||||
cifs_sb = CIFS_SB(inode->i_sb);
|
cifs_sb = CIFS_SB(inode->i_sb);
|
||||||
pTcon = cifs_sb->tcon;
|
pTcon = cifs_sb->tcon;
|
||||||
|
|
||||||
mutex_lock(&inode->i_sb->s_vfs_rename_mutex);
|
|
||||||
full_path = build_path_from_dentry(direntry);
|
full_path = build_path_from_dentry(direntry);
|
||||||
mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);
|
|
||||||
if (full_path == NULL) {
|
if (full_path == NULL) {
|
||||||
FreeXid(xid);
|
FreeXid(xid);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -1141,9 +1137,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
|
|||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&direntry->d_sb->s_vfs_rename_mutex);
|
|
||||||
full_path = build_path_from_dentry(direntry);
|
full_path = build_path_from_dentry(direntry);
|
||||||
mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex);
|
|
||||||
if (full_path == NULL) {
|
if (full_path == NULL) {
|
||||||
FreeXid(xid);
|
FreeXid(xid);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -48,10 +48,8 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
|
|||||||
/* No need to check for cross device links since server will do that
|
/* No need to check for cross device links since server will do that
|
||||||
BB note DFS case in future though (when we may have to check) */
|
BB note DFS case in future though (when we may have to check) */
|
||||||
|
|
||||||
mutex_lock(&inode->i_sb->s_vfs_rename_mutex);
|
|
||||||
fromName = build_path_from_dentry(old_file);
|
fromName = build_path_from_dentry(old_file);
|
||||||
toName = build_path_from_dentry(direntry);
|
toName = build_path_from_dentry(direntry);
|
||||||
mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);
|
|
||||||
if((fromName == NULL) || (toName == NULL)) {
|
if((fromName == NULL) || (toName == NULL)) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
goto cifs_hl_exit;
|
goto cifs_hl_exit;
|
||||||
@ -103,9 +101,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
|
|||||||
|
|
||||||
xid = GetXid();
|
xid = GetXid();
|
||||||
|
|
||||||
mutex_lock(&direntry->d_sb->s_vfs_rename_mutex);
|
|
||||||
full_path = build_path_from_dentry(direntry);
|
full_path = build_path_from_dentry(direntry);
|
||||||
mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex);
|
|
||||||
|
|
||||||
if (!full_path)
|
if (!full_path)
|
||||||
goto out_no_free;
|
goto out_no_free;
|
||||||
@ -164,9 +160,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
|
|||||||
cifs_sb = CIFS_SB(inode->i_sb);
|
cifs_sb = CIFS_SB(inode->i_sb);
|
||||||
pTcon = cifs_sb->tcon;
|
pTcon = cifs_sb->tcon;
|
||||||
|
|
||||||
mutex_lock(&inode->i_sb->s_vfs_rename_mutex);
|
|
||||||
full_path = build_path_from_dentry(direntry);
|
full_path = build_path_from_dentry(direntry);
|
||||||
mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);
|
|
||||||
|
|
||||||
if(full_path == NULL) {
|
if(full_path == NULL) {
|
||||||
FreeXid(xid);
|
FreeXid(xid);
|
||||||
|
@ -121,6 +121,20 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, const int type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* copy session key */
|
||||||
|
|
||||||
|
/* if Unicode, align strings to two byte boundary */
|
||||||
|
|
||||||
|
/* copy user name */ /* BB Do we need to special case null user name? */
|
||||||
|
|
||||||
|
/* copy domain name */
|
||||||
|
|
||||||
|
/* copy Linux version */
|
||||||
|
|
||||||
|
/* copy network operating system name */
|
||||||
|
|
||||||
|
/* update bcc and smb buffer length */
|
||||||
|
|
||||||
/* rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buf_type, 0); */
|
/* rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buf_type, 0); */
|
||||||
/* SMB request buf freed in SendReceive2 */
|
/* SMB request buf freed in SendReceive2 */
|
||||||
|
|
||||||
|
@ -404,9 +404,7 @@ static int initiate_cifs_search(const int xid, struct file *file)
|
|||||||
if(pTcon == NULL)
|
if(pTcon == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
mutex_lock(&file->f_dentry->d_sb->s_vfs_rename_mutex);
|
|
||||||
full_path = build_path_from_dentry(file->f_dentry);
|
full_path = build_path_from_dentry(file->f_dentry);
|
||||||
mutex_unlock(&file->f_dentry->d_sb->s_vfs_rename_mutex);
|
|
||||||
|
|
||||||
if(full_path == NULL) {
|
if(full_path == NULL) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -592,6 +590,13 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
|
|||||||
first_entry_in_buffer =
|
first_entry_in_buffer =
|
||||||
cifsFile->srch_inf.index_of_last_entry -
|
cifsFile->srch_inf.index_of_last_entry -
|
||||||
cifsFile->srch_inf.entries_in_buffer;
|
cifsFile->srch_inf.entries_in_buffer;
|
||||||
|
|
||||||
|
/* if first entry in buf is zero then is first buffer
|
||||||
|
in search response data which means it is likely . and ..
|
||||||
|
will be in this buffer, although some servers do not return
|
||||||
|
. and .. for the root of a drive and for those we need
|
||||||
|
to start two entries earlier */
|
||||||
|
|
||||||
/* dump_cifs_file_struct(file, "In fce ");*/
|
/* dump_cifs_file_struct(file, "In fce ");*/
|
||||||
if(((index_to_find < cifsFile->srch_inf.index_of_last_entry) &&
|
if(((index_to_find < cifsFile->srch_inf.index_of_last_entry) &&
|
||||||
is_dir_changed(file)) ||
|
is_dir_changed(file)) ||
|
||||||
@ -634,23 +639,14 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
|
|||||||
char * end_of_smb = cifsFile->srch_inf.ntwrk_buf_start +
|
char * end_of_smb = cifsFile->srch_inf.ntwrk_buf_start +
|
||||||
smbCalcSize((struct smb_hdr *)
|
smbCalcSize((struct smb_hdr *)
|
||||||
cifsFile->srch_inf.ntwrk_buf_start);
|
cifsFile->srch_inf.ntwrk_buf_start);
|
||||||
|
|
||||||
|
current_entry = cifsFile->srch_inf.srch_entries_start;
|
||||||
first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry
|
first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry
|
||||||
- cifsFile->srch_inf.entries_in_buffer;
|
- cifsFile->srch_inf.entries_in_buffer;
|
||||||
pos_in_buf = index_to_find - first_entry_in_buffer;
|
pos_in_buf = index_to_find - first_entry_in_buffer;
|
||||||
cFYI(1,("found entry - pos_in_buf %d",pos_in_buf));
|
cFYI(1,("found entry - pos_in_buf %d",pos_in_buf));
|
||||||
current_entry = cifsFile->srch_inf.srch_entries_start;
|
|
||||||
for(i=0;(i<(pos_in_buf)) && (current_entry != NULL);i++) {
|
for(i=0;(i<(pos_in_buf)) && (current_entry != NULL);i++) {
|
||||||
/* go entry by entry figuring out which is first */
|
/* go entry by entry figuring out which is first */
|
||||||
/* if( . or ..)
|
|
||||||
skip */
|
|
||||||
rc = cifs_entry_is_dot(current_entry,cifsFile);
|
|
||||||
if(rc == 1) /* is . or .. so skip */ {
|
|
||||||
cFYI(1,("Entry is .")); /* BB removeme BB */
|
|
||||||
/* continue; */
|
|
||||||
} else if (rc == 2 ) {
|
|
||||||
cFYI(1,("Entry is ..")); /* BB removeme BB */
|
|
||||||
/* continue; */
|
|
||||||
}
|
|
||||||
current_entry = nxt_dir_entry(current_entry,end_of_smb);
|
current_entry = nxt_dir_entry(current_entry,end_of_smb);
|
||||||
}
|
}
|
||||||
if((current_entry == NULL) && (i < pos_in_buf)) {
|
if((current_entry == NULL) && (i < pos_in_buf)) {
|
||||||
@ -770,6 +766,11 @@ static int cifs_filldir(char *pfindEntry, struct file *file,
|
|||||||
if(file->f_dentry == NULL)
|
if(file->f_dentry == NULL)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
|
rc = cifs_entry_is_dot(pfindEntry,pCifsF);
|
||||||
|
/* skip . and .. since we added them first */
|
||||||
|
if(rc != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
cifs_sb = CIFS_SB(file->f_dentry->d_sb);
|
cifs_sb = CIFS_SB(file->f_dentry->d_sb);
|
||||||
|
|
||||||
qstring.name = scratch_buf;
|
qstring.name = scratch_buf;
|
||||||
@ -898,22 +899,22 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
|
|||||||
|
|
||||||
switch ((int) file->f_pos) {
|
switch ((int) file->f_pos) {
|
||||||
case 0:
|
case 0:
|
||||||
/*if (filldir(direntry, ".", 1, file->f_pos,
|
if (filldir(direntry, ".", 1, file->f_pos,
|
||||||
file->f_dentry->d_inode->i_ino, DT_DIR) < 0) {
|
file->f_dentry->d_inode->i_ino, DT_DIR) < 0) {
|
||||||
cERROR(1, ("Filldir for current dir failed "));
|
cERROR(1, ("Filldir for current dir failed"));
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
file->f_pos++; */
|
file->f_pos++;
|
||||||
case 1:
|
case 1:
|
||||||
/* if (filldir(direntry, "..", 2, file->f_pos,
|
if (filldir(direntry, "..", 2, file->f_pos,
|
||||||
file->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) {
|
file->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) {
|
||||||
cERROR(1, ("Filldir for parent dir failed "));
|
cERROR(1, ("Filldir for parent dir failed "));
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
file->f_pos++; */
|
file->f_pos++;
|
||||||
case 2:
|
default:
|
||||||
/* 1) If search is active,
|
/* 1) If search is active,
|
||||||
is in current search buffer?
|
is in current search buffer?
|
||||||
if it before then restart search
|
if it before then restart search
|
||||||
@ -927,7 +928,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
if(file->private_data == NULL) {
|
if(file->private_data == NULL) {
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
FreeXid(xid);
|
FreeXid(xid);
|
||||||
@ -947,8 +947,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
|
|||||||
kfree(cifsFile->search_resume_name);
|
kfree(cifsFile->search_resume_name);
|
||||||
cifsFile->search_resume_name = NULL; */
|
cifsFile->search_resume_name = NULL; */
|
||||||
|
|
||||||
/* BB account for . and .. in f_pos as special case */
|
|
||||||
|
|
||||||
rc = find_cifs_entry(xid,pTcon, file,
|
rc = find_cifs_entry(xid,pTcon, file,
|
||||||
¤t_entry,&num_to_fill);
|
¤t_entry,&num_to_fill);
|
||||||
if(rc) {
|
if(rc) {
|
||||||
@ -977,7 +975,8 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
|
|||||||
num_to_fill, i));
|
num_to_fill, i));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/* if buggy server returns . and .. late do
|
||||||
|
we want to check for that here? */
|
||||||
rc = cifs_filldir(current_entry, file,
|
rc = cifs_filldir(current_entry, file,
|
||||||
filldir, direntry,tmp_buf);
|
filldir, direntry,tmp_buf);
|
||||||
file->f_pos++;
|
file->f_pos++;
|
||||||
|
@ -62,9 +62,7 @@ int cifs_removexattr(struct dentry * direntry, const char * ea_name)
|
|||||||
cifs_sb = CIFS_SB(sb);
|
cifs_sb = CIFS_SB(sb);
|
||||||
pTcon = cifs_sb->tcon;
|
pTcon = cifs_sb->tcon;
|
||||||
|
|
||||||
mutex_lock(&sb->s_vfs_rename_mutex);
|
|
||||||
full_path = build_path_from_dentry(direntry);
|
full_path = build_path_from_dentry(direntry);
|
||||||
mutex_unlock(&sb->s_vfs_rename_mutex);
|
|
||||||
if(full_path == NULL) {
|
if(full_path == NULL) {
|
||||||
FreeXid(xid);
|
FreeXid(xid);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -116,9 +114,7 @@ int cifs_setxattr(struct dentry * direntry, const char * ea_name,
|
|||||||
cifs_sb = CIFS_SB(sb);
|
cifs_sb = CIFS_SB(sb);
|
||||||
pTcon = cifs_sb->tcon;
|
pTcon = cifs_sb->tcon;
|
||||||
|
|
||||||
mutex_lock(&sb->s_vfs_rename_mutex);
|
|
||||||
full_path = build_path_from_dentry(direntry);
|
full_path = build_path_from_dentry(direntry);
|
||||||
mutex_unlock(&sb->s_vfs_rename_mutex);
|
|
||||||
if(full_path == NULL) {
|
if(full_path == NULL) {
|
||||||
FreeXid(xid);
|
FreeXid(xid);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -223,9 +219,7 @@ ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name,
|
|||||||
cifs_sb = CIFS_SB(sb);
|
cifs_sb = CIFS_SB(sb);
|
||||||
pTcon = cifs_sb->tcon;
|
pTcon = cifs_sb->tcon;
|
||||||
|
|
||||||
mutex_lock(&sb->s_vfs_rename_mutex);
|
|
||||||
full_path = build_path_from_dentry(direntry);
|
full_path = build_path_from_dentry(direntry);
|
||||||
mutex_unlock(&sb->s_vfs_rename_mutex);
|
|
||||||
if(full_path == NULL) {
|
if(full_path == NULL) {
|
||||||
FreeXid(xid);
|
FreeXid(xid);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -341,9 +335,7 @@ ssize_t cifs_listxattr(struct dentry * direntry, char * data, size_t buf_size)
|
|||||||
cifs_sb = CIFS_SB(sb);
|
cifs_sb = CIFS_SB(sb);
|
||||||
pTcon = cifs_sb->tcon;
|
pTcon = cifs_sb->tcon;
|
||||||
|
|
||||||
mutex_lock(&sb->s_vfs_rename_mutex);
|
|
||||||
full_path = build_path_from_dentry(direntry);
|
full_path = build_path_from_dentry(direntry);
|
||||||
mutex_unlock(&sb->s_vfs_rename_mutex);
|
|
||||||
if(full_path == NULL) {
|
if(full_path == NULL) {
|
||||||
FreeXid(xid);
|
FreeXid(xid);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
Loading…
Reference in New Issue
Block a user