From: Greg KH <gregkh@suse.de>
To: linux-kernel@vger.kernel.org, stable@kernel.org
Cc: Justin Forbes <jmforbes@linuxtx.org>,
Zwane Mwaikambo <zwane@arm.linux.org.uk>,
"Theodore Ts'o" <tytso@mit.edu>,
Randy Dunlap <rdunlap@xenotime.net>,
Dave Jones <davej@redhat.com>,
Chuck Wolber <chuckw@quantumlinux.com>,
Chris Wedgwood <reviews@ml.cw.f00f.org>,
Michael Krufky <mkrufky@linuxtv.org>,
Chuck Ebbert <cebbert@redhat.com>,
Domenico Andreoli <cavokz@gmail.com>, Willy Tarreau <w@1wt.eu>,
Rodrigo Rubira Branco <rbranco@la.checkpoint.com>,
Jake Edge <jake@lwn.net>, Eugene Teo <eteo@redhat.com>,
torvalds@linux-foundation.org, akpm@linux-foundation.org,
alan@lxorguk.ukuu.org.uk, Steve French <smfrench@gmail.com>,
Jeff Layton <jlayton@redhat.com>,
Steve French <sfrench@us.ibm.com>,
Suresh Jayaraman <sjayaraman@suse.de>
Subject: [patch 072/104] cifs: reinstate sharing of SMB sessions sans races
Date: Wed, 3 Dec 2008 11:53:34 -0800 [thread overview]
Message-ID: <20081203195334.GU8950@kroah.com> (raw)
In-Reply-To: <20081203194725.GA8950@kroah.com>
[-- Attachment #1: cifs-reinstate-sharing-of-smb-sessions-sans-races.patch --]
[-- Type: text/plain, Size: 20786 bytes --]
2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jeff Layton <jlayton@redhat.com>
commit 14fbf50d695207754daeb96270b3027a3821121f upstream
We do this by abandoning the global list of SMB sessions and instead
moving to a per-server list. This entails adding a new list head to the
TCP_Server_Info struct. The refcounting for the cifsSesInfo is moved to
a non-atomic variable. We have to protect it by a lock anyway, so there's
no benefit to making it an atomic. The list and refcount are protected
by the global cifs_tcp_ses_lock.
The patch also adds a new routines to find and put SMB sessions and
that properly take and put references under the lock.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Cc: Suresh Jayaraman <sjayaraman@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
fs/cifs/cifs_debug.c | 53 ++++++------
fs/cifs/cifsfs.c | 17 +--
fs/cifs/cifsglob.h | 6 -
fs/cifs/cifsproto.h | 1
fs/cifs/cifssmb.c | 22 +---
fs/cifs/connect.c | 225 ++++++++++++++++++++++++++++-----------------------
fs/cifs/misc.c | 16 +--
7 files changed, 174 insertions(+), 166 deletions(-)
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -107,9 +107,9 @@ void cifs_dump_mids(struct TCP_Server_In
#ifdef CONFIG_PROC_FS
static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
{
- struct list_head *tmp;
- struct list_head *tmp1;
+ struct list_head *tmp, *tmp2, *tmp3;
struct mid_q_entry *mid_entry;
+ struct TCP_Server_Info *server;
struct cifsSesInfo *ses;
struct cifsTconInfo *tcon;
int i;
@@ -122,43 +122,45 @@ static int cifs_debug_data_proc_show(str
seq_printf(m, "Servers:");
i = 0;
- read_lock(&GlobalSMBSeslock);
- list_for_each(tmp, &GlobalSMBSessionList) {
+ read_lock(&cifs_tcp_ses_lock);
+ list_for_each(tmp, &cifs_tcp_ses_list) {
+ server = list_entry(tmp, struct TCP_Server_Info,
+ tcp_ses_list);
i++;
- ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
- if ((ses->serverDomain == NULL) || (ses->serverOS == NULL) ||
- (ses->serverNOS == NULL)) {
- seq_printf(m, "\nentry for %s not fully "
- "displayed\n\t", ses->serverName);
- } else {
- seq_printf(m,
+ list_for_each(tmp2, &server->smb_ses_list) {
+ ses = list_entry(tmp2, struct cifsSesInfo,
+ smb_ses_list);
+ if ((ses->serverDomain == NULL) ||
+ (ses->serverOS == NULL) ||
+ (ses->serverNOS == NULL)) {
+ seq_printf(m, "\nentry for %s not fully "
+ "displayed\n\t", ses->serverName);
+ } else {
+ seq_printf(m,
"\n%d) Name: %s Domain: %s Mounts: %d OS:"
" %s \n\tNOS: %s\tCapability: 0x%x\n\tSMB"
" session status: %d\t",
i, ses->serverName, ses->serverDomain,
- atomic_read(&ses->inUse),
- ses->serverOS, ses->serverNOS,
+ ses->ses_count, ses->serverOS, ses->serverNOS,
ses->capabilities, ses->status);
- }
- if (ses->server) {
+ }
seq_printf(m, "TCP status: %d\n\tLocal Users To "
- "Server: %d SecMode: 0x%x Req On Wire: %d",
- ses->server->tcpStatus,
- ses->server->srv_count,
- ses->server->secMode,
- atomic_read(&ses->server->inFlight));
+ "Server: %d SecMode: 0x%x Req On Wire: %d",
+ server->tcpStatus, server->srv_count,
+ server->secMode,
+ atomic_read(&server->inFlight));
#ifdef CONFIG_CIFS_STATS2
seq_printf(m, " In Send: %d In MaxReq Wait: %d",
- atomic_read(&ses->server->inSend),
- atomic_read(&ses->server->num_waiters));
+ atomic_read(&server->inSend),
+ atomic_read(&server->num_waiters));
#endif
seq_puts(m, "\nMIDs:\n");
spin_lock(&GlobalMid_Lock);
- list_for_each(tmp1, &ses->server->pending_mid_q) {
- mid_entry = list_entry(tmp1, struct
+ list_for_each(tmp3, &server->pending_mid_q) {
+ mid_entry = list_entry(tmp3, struct
mid_q_entry,
qhead);
seq_printf(m, "State: %d com: %d pid:"
@@ -171,9 +173,8 @@ static int cifs_debug_data_proc_show(str
}
spin_unlock(&GlobalMid_Lock);
}
-
}
- read_unlock(&GlobalSMBSeslock);
+ read_unlock(&cifs_tcp_ses_lock);
seq_putc(m, '\n');
seq_puts(m, "Shares:");
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -985,24 +985,24 @@ static int cifs_oplock_thread(void *dumm
static int cifs_dnotify_thread(void *dummyarg)
{
struct list_head *tmp;
- struct cifsSesInfo *ses;
+ struct TCP_Server_Info *server;
do {
if (try_to_freeze())
continue;
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(15*HZ);
- read_lock(&GlobalSMBSeslock);
/* check if any stuck requests that need
to be woken up and wakeq so the
thread can wake up and error out */
- list_for_each(tmp, &GlobalSMBSessionList) {
- ses = list_entry(tmp, struct cifsSesInfo,
- cifsSessionList);
- if (ses->server && atomic_read(&ses->server->inFlight))
- wake_up_all(&ses->server->response_q);
+ read_lock(&cifs_tcp_ses_lock);
+ list_for_each(tmp, &cifs_tcp_ses_list) {
+ server = list_entry(tmp, struct TCP_Server_Info,
+ tcp_ses_list);
+ if (atomic_read(&server->inFlight))
+ wake_up_all(&server->response_q);
}
- read_unlock(&GlobalSMBSeslock);
+ read_unlock(&cifs_tcp_ses_lock);
} while (!kthread_should_stop());
return 0;
@@ -1014,7 +1014,6 @@ init_cifs(void)
int rc = 0;
cifs_proc_init();
INIT_LIST_HEAD(&cifs_tcp_ses_list);
- INIT_LIST_HEAD(&GlobalSMBSessionList); /* BB to be removed by jl */
INIT_LIST_HEAD(&GlobalTreeConnectionList); /* BB to be removed by jl */
INIT_LIST_HEAD(&GlobalOplock_Q);
#ifdef CONFIG_CIFS_EXPERIMENTAL
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -195,14 +195,14 @@ struct cifsUidInfo {
* Session structure. One of these for each uid session with a particular host
*/
struct cifsSesInfo {
- struct list_head cifsSessionList;
+ struct list_head smb_ses_list;
struct list_head tcon_list;
struct semaphore sesSem;
#if 0
struct cifsUidInfo *uidInfo; /* pointer to user info */
#endif
struct TCP_Server_Info *server; /* pointer to server info */
- atomic_t inUse; /* # of mounts (tree connections) on this ses */
+ int ses_count; /* reference counter */
enum statusEnum status;
unsigned overrideSecFlg; /* if non-zero override global sec flags */
__u16 ipc_tid; /* special tid for connection to IPC share */
@@ -600,8 +600,6 @@ GLOBAL_EXTERN struct list_head cifs_tcp
/* protects cifs_tcp_ses_list and srv_count for each tcp session */
GLOBAL_EXTERN rwlock_t cifs_tcp_ses_lock;
-
-GLOBAL_EXTERN struct list_head GlobalSMBSessionList; /* BB to be removed by jl*/
GLOBAL_EXTERN struct list_head GlobalTreeConnectionList; /* BB to be removed */
GLOBAL_EXTERN rwlock_t GlobalSMBSeslock; /* protects list inserts on 3 above */
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -102,7 +102,6 @@ extern void acl_to_uid_mode(struct inode
const __u16 *pfid);
extern int mode_to_acl(struct inode *inode, const char *path, __u64);
-extern void cifs_put_tcp_session(struct TCP_Server_Info *server);
extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *,
const char *);
extern int cifs_umount(struct super_block *, struct cifs_sb_info *);
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -799,20 +799,16 @@ CIFSSMBLogoff(const int xid, struct cifs
int rc = 0;
cFYI(1, ("In SMBLogoff for session disconnect"));
- if (ses)
- down(&ses->sesSem);
- else
- return -EIO;
-
- atomic_dec(&ses->inUse);
- if (atomic_read(&ses->inUse) > 0) {
- up(&ses->sesSem);
- return -EBUSY;
- }
- if (ses->server == NULL)
+ /*
+ * BB: do we need to check validity of ses and server? They should
+ * always be valid since we have an active reference. If not, that
+ * should probably be a BUG()
+ */
+ if (!ses || !ses->server)
return -EIO;
+ down(&ses->sesSem);
if (ses->need_reconnect)
goto session_already_dead; /* no need to send SMBlogoff if uid
already closed due to reconnect */
@@ -833,10 +829,6 @@ CIFSSMBLogoff(const int xid, struct cifs
pSMB->AndXCommand = 0xFF;
rc = SendReceiveNoRsp(xid, ses, (struct smb_hdr *) pSMB, 0);
session_already_dead:
- if (ses->server) {
- cifs_put_tcp_session(ses->server);
- rc = 0;
- }
up(&ses->sesSem);
/* if session dead then we do not need to do ulogoff,
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -142,23 +142,18 @@ cifs_reconnect(struct TCP_Server_Info *s
/* before reconnecting the tcp session, mark the smb session (uid)
and the tid bad so they are not used until reconnected */
- read_lock(&GlobalSMBSeslock);
- list_for_each(tmp, &GlobalSMBSessionList) {
- ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
- if (ses->server) {
- if (ses->server == server) {
- ses->need_reconnect = true;
- ses->ipc_tid = 0;
- }
- }
- /* else tcp and smb sessions need reconnection */
+ read_lock(&cifs_tcp_ses_lock);
+ list_for_each(tmp, &server->smb_ses_list) {
+ ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
+ ses->need_reconnect = true;
+ ses->ipc_tid = 0;
}
+ read_unlock(&cifs_tcp_ses_lock);
list_for_each(tmp, &GlobalTreeConnectionList) {
tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
if ((tcon->ses) && (tcon->ses->server == server))
tcon->need_reconnect = true;
}
- read_unlock(&GlobalSMBSeslock);
/* do not want to be sending data on a socket we are freeing */
down(&server->tcpSem);
if (server->ssocket) {
@@ -702,29 +697,29 @@ multi_t2_fnd:
if (smallbuf) /* no sense logging a debug message if NULL */
cifs_small_buf_release(smallbuf);
- read_lock(&GlobalSMBSeslock);
+ /*
+ * BB: we shouldn't have to do any of this. It shouldn't be
+ * possible to exit from the thread with active SMB sessions
+ */
+ read_lock(&cifs_tcp_ses_lock);
if (list_empty(&server->pending_mid_q)) {
/* loop through server session structures attached to this and
mark them dead */
- list_for_each(tmp, &GlobalSMBSessionList) {
- ses =
- list_entry(tmp, struct cifsSesInfo,
- cifsSessionList);
- if (ses->server == server) {
- ses->status = CifsExiting;
- ses->server = NULL;
- }
+ list_for_each(tmp, &server->smb_ses_list) {
+ ses = list_entry(tmp, struct cifsSesInfo,
+ smb_ses_list);
+ ses->status = CifsExiting;
+ ses->server = NULL;
}
- read_unlock(&GlobalSMBSeslock);
+ read_unlock(&cifs_tcp_ses_lock);
} else {
/* although we can not zero the server struct pointer yet,
since there are active requests which may depnd on them,
mark the corresponding SMB sessions as exiting too */
- list_for_each(tmp, &GlobalSMBSessionList) {
+ list_for_each(tmp, &server->smb_ses_list) {
ses = list_entry(tmp, struct cifsSesInfo,
- cifsSessionList);
- if (ses->server == server)
- ses->status = CifsExiting;
+ smb_ses_list);
+ ses->status = CifsExiting;
}
spin_lock(&GlobalMid_Lock);
@@ -739,7 +734,7 @@ multi_t2_fnd:
}
}
spin_unlock(&GlobalMid_Lock);
- read_unlock(&GlobalSMBSeslock);
+ read_unlock(&cifs_tcp_ses_lock);
/* 1/8th of sec is more than enough time for them to exit */
msleep(125);
}
@@ -761,14 +756,13 @@ multi_t2_fnd:
if there are any pointing to this (e.g
if a crazy root user tried to kill cifsd
kernel thread explicitly this might happen) */
- write_lock(&GlobalSMBSeslock);
- list_for_each(tmp, &GlobalSMBSessionList) {
- ses = list_entry(tmp, struct cifsSesInfo,
- cifsSessionList);
- if (ses->server == server)
- ses->server = NULL;
+ /* BB: This shouldn't be necessary, see above */
+ read_lock(&cifs_tcp_ses_lock);
+ list_for_each(tmp, &server->smb_ses_list) {
+ ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
+ ses->server = NULL;
}
- write_unlock(&GlobalSMBSeslock);
+ read_unlock(&cifs_tcp_ses_lock);
kfree(server->hostname);
kfree(server);
@@ -1390,7 +1384,7 @@ cifs_find_tcp_session(struct sockaddr *a
return NULL;
}
-void
+static void
cifs_put_tcp_session(struct TCP_Server_Info *server)
{
struct task_struct *task;
@@ -1413,6 +1407,50 @@ cifs_put_tcp_session(struct TCP_Server_I
force_sig(SIGKILL, task);
}
+static struct cifsSesInfo *
+cifs_find_smb_ses(struct TCP_Server_Info *server, char *username)
+{
+ struct list_head *tmp;
+ struct cifsSesInfo *ses;
+
+ write_lock(&cifs_tcp_ses_lock);
+ list_for_each(tmp, &server->smb_ses_list) {
+ ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
+ if (strncmp(ses->userName, username, MAX_USERNAME_SIZE))
+ continue;
+
+ ++ses->ses_count;
+ write_unlock(&cifs_tcp_ses_lock);
+ return ses;
+ }
+ write_unlock(&cifs_tcp_ses_lock);
+ return NULL;
+}
+
+static void
+cifs_put_smb_ses(struct cifsSesInfo *ses)
+{
+ int xid;
+ struct TCP_Server_Info *server = ses->server;
+
+ write_lock(&cifs_tcp_ses_lock);
+ if (--ses->ses_count > 0) {
+ write_unlock(&cifs_tcp_ses_lock);
+ return;
+ }
+
+ list_del_init(&ses->smb_ses_list);
+ write_unlock(&cifs_tcp_ses_lock);
+
+ if (ses->status == CifsGood) {
+ xid = GetXid();
+ CIFSSMBLogoff(xid, ses);
+ _FreeXid(xid);
+ }
+ sesInfoFree(ses);
+ cifs_put_tcp_session(server);
+}
+
int
get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
@@ -1945,7 +1983,6 @@ cifs_mount(struct super_block *sb, struc
struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) &addr;
struct smb_vol volume_info;
struct cifsSesInfo *pSesInfo = NULL;
- struct cifsSesInfo *existingCifsSes = NULL;
struct cifsTconInfo *tcon = NULL;
struct TCP_Server_Info *srvTcp = NULL;
@@ -2099,6 +2136,7 @@ cifs_mount(struct super_block *sb, struc
volume_info.target_rfc1001_name, 16);
srvTcp->sequence_number = 0;
INIT_LIST_HEAD(&srvTcp->tcp_ses_list);
+ INIT_LIST_HEAD(&srvTcp->smb_ses_list);
++srvTcp->srv_count;
write_lock(&cifs_tcp_ses_lock);
list_add(&srvTcp->tcp_ses_list,
@@ -2107,10 +2145,16 @@ cifs_mount(struct super_block *sb, struc
}
}
- if (existingCifsSes) {
- pSesInfo = existingCifsSes;
+ pSesInfo = cifs_find_smb_ses(srvTcp, volume_info.username);
+ if (pSesInfo) {
cFYI(1, ("Existing smb sess found (status=%d)",
pSesInfo->status));
+ /*
+ * The existing SMB session already has a reference to srvTcp,
+ * so we can put back the extra one we got before
+ */
+ cifs_put_tcp_session(srvTcp);
+
down(&pSesInfo->sesSem);
if (pSesInfo->need_reconnect) {
cFYI(1, ("Session needs reconnect"));
@@ -2121,41 +2165,44 @@ cifs_mount(struct super_block *sb, struc
} else if (!rc) {
cFYI(1, ("Existing smb sess not found"));
pSesInfo = sesInfoAlloc();
- if (pSesInfo == NULL)
+ if (pSesInfo == NULL) {
rc = -ENOMEM;
- else {
- pSesInfo->server = srvTcp;
- sprintf(pSesInfo->serverName, "%u.%u.%u.%u",
- NIPQUAD(sin_server->sin_addr.s_addr));
+ goto mount_fail_check;
}
- if (!rc) {
- /* volume_info.password freed at unmount */
- if (volume_info.password) {
- pSesInfo->password = volume_info.password;
- /* set to NULL to prevent freeing on exit */
- volume_info.password = NULL;
- }
- if (volume_info.username)
- strncpy(pSesInfo->userName,
- volume_info.username,
- MAX_USERNAME_SIZE);
- if (volume_info.domainname) {
- int len = strlen(volume_info.domainname);
- pSesInfo->domainName =
- kmalloc(len + 1, GFP_KERNEL);
- if (pSesInfo->domainName)
- strcpy(pSesInfo->domainName,
- volume_info.domainname);
- }
- pSesInfo->linux_uid = volume_info.linux_uid;
- pSesInfo->overrideSecFlg = volume_info.secFlg;
- down(&pSesInfo->sesSem);
- /* BB FIXME need to pass vol->secFlgs BB */
- rc = cifs_setup_session(xid, pSesInfo,
- cifs_sb->local_nls);
- up(&pSesInfo->sesSem);
+ /* new SMB session uses our srvTcp ref */
+ pSesInfo->server = srvTcp;
+ sprintf(pSesInfo->serverName, "%u.%u.%u.%u",
+ NIPQUAD(sin_server->sin_addr.s_addr));
+
+ write_lock(&cifs_tcp_ses_lock);
+ list_add(&pSesInfo->smb_ses_list, &srvTcp->smb_ses_list);
+ write_unlock(&cifs_tcp_ses_lock);
+
+ /* volume_info.password freed at unmount */
+ if (volume_info.password) {
+ pSesInfo->password = volume_info.password;
+ /* set to NULL to prevent freeing on exit */
+ volume_info.password = NULL;
+ }
+ if (volume_info.username)
+ strncpy(pSesInfo->userName, volume_info.username,
+ MAX_USERNAME_SIZE);
+ if (volume_info.domainname) {
+ int len = strlen(volume_info.domainname);
+ pSesInfo->domainName = kmalloc(len + 1, GFP_KERNEL);
+ if (pSesInfo->domainName)
+ strcpy(pSesInfo->domainName,
+ volume_info.domainname);
}
+ pSesInfo->linux_uid = volume_info.linux_uid;
+ pSesInfo->overrideSecFlg = volume_info.secFlg;
+ down(&pSesInfo->sesSem);
+
+ /* BB FIXME need to pass vol->secFlgs BB */
+ rc = cifs_setup_session(xid, pSesInfo,
+ cifs_sb->local_nls);
+ up(&pSesInfo->sesSem);
}
/* search for existing tcon to this server share */
@@ -2190,11 +2237,9 @@ cifs_mount(struct super_block *sb, struc
tcon, cifs_sb->local_nls);
cFYI(1, ("CIFS Tcon rc = %d", rc));
}
- if (!rc) {
- atomic_inc(&pSesInfo->inUse);
- tcon->seal = volume_info.seal;
- } else
+ if (rc)
goto mount_fail_check;
+ tcon->seal = volume_info.seal;
}
/* we can have only one retry value for a connection
@@ -2214,7 +2259,7 @@ cifs_mount(struct super_block *sb, struc
/* BB FIXME fix time_gran to be larger for LANMAN sessions */
sb->s_time_gran = 100;
-/* on error free sesinfo and tcon struct if needed */
+ /* on error free sesinfo and tcon struct if needed */
mount_fail_check:
if (rc) {
/* If find_unc succeeded then rc == 0 so we can not end */
@@ -2222,21 +2267,11 @@ mount_fail_check:
if (tcon)
tconInfoFree(tcon);
- if (existingCifsSes == NULL) {
- if (pSesInfo) {
- if ((pSesInfo->server) &&
- (pSesInfo->status == CifsGood))
- CIFSSMBLogoff(xid, pSesInfo);
- else {
- cFYI(1, ("No session or bad tcon"));
- }
- if (pSesInfo->server)
- cifs_put_tcp_session(
- pSesInfo->server);
- sesInfoFree(pSesInfo);
- /* pSesInfo = NULL; */
- }
- }
+ /* should also end up putting our tcp session ref if needed */
+ if (pSesInfo)
+ cifs_put_smb_ses(pSesInfo);
+ else
+ cifs_put_tcp_session(srvTcp);
} else {
atomic_inc(&tcon->useCount);
cifs_sb->tcon = tcon;
@@ -3532,17 +3567,7 @@ cifs_umount(struct super_block *sb, stru
}
DeleteTconOplockQEntries(cifs_sb->tcon);
tconInfoFree(cifs_sb->tcon);
- if ((ses) && (ses->server)) {
- /* save off task so we do not refer to ses later */
- cifsd_task = ses->server->tsk;
- cFYI(1, ("About to do SMBLogoff "));
- rc = CIFSSMBLogoff(xid, ses);
- if (rc == -EBUSY) {
- FreeXid(xid);
- return 0;
- }
- } else
- cFYI(1, ("No session or bad tcon"));
+ cifs_put_smb_ses(ses);
}
cifs_sb->tcon = NULL;
@@ -3550,8 +3575,6 @@ cifs_umount(struct super_block *sb, stru
cifs_sb->prepathlen = 0;
cifs_sb->prepath = NULL;
kfree(tmp);
- if (ses)
- sesInfoFree(ses);
FreeXid(xid);
return rc;
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -75,12 +75,11 @@ sesInfoAlloc(void)
ret_buf = kzalloc(sizeof(struct cifsSesInfo), GFP_KERNEL);
if (ret_buf) {
- write_lock(&GlobalSMBSeslock);
atomic_inc(&sesInfoAllocCount);
ret_buf->status = CifsNew;
- list_add(&ret_buf->cifsSessionList, &GlobalSMBSessionList);
+ ++ret_buf->ses_count;
+ INIT_LIST_HEAD(&ret_buf->smb_ses_list);
init_MUTEX(&ret_buf->sesSem);
- write_unlock(&GlobalSMBSeslock);
}
return ret_buf;
}
@@ -93,10 +92,7 @@ sesInfoFree(struct cifsSesInfo *buf_to_f
return;
}
- write_lock(&GlobalSMBSeslock);
atomic_dec(&sesInfoAllocCount);
- list_del(&buf_to_free->cifsSessionList);
- write_unlock(&GlobalSMBSeslock);
kfree(buf_to_free->serverOS);
kfree(buf_to_free->serverDomain);
kfree(buf_to_free->serverNOS);
@@ -354,9 +350,9 @@ header_assemble(struct smb_hdr *buffer,
if (current->fsuid != treeCon->ses->linux_uid) {
cFYI(1, ("Multiuser mode and UID "
"did not match tcon uid"));
- read_lock(&GlobalSMBSeslock);
- list_for_each(temp_item, &GlobalSMBSessionList) {
- ses = list_entry(temp_item, struct cifsSesInfo, cifsSessionList);
+ read_lock(&cifs_tcp_ses_lock);
+ list_for_each(temp_item, &treeCon->ses->server->smb_ses_list) {
+ ses = list_entry(temp_item, struct cifsSesInfo, smb_ses_list);
if (ses->linux_uid == current->fsuid) {
if (ses->server == treeCon->ses->server) {
cFYI(1, ("found matching uid substitute right smb_uid"));
@@ -368,7 +364,7 @@ header_assemble(struct smb_hdr *buffer,
}
}
}
- read_unlock(&GlobalSMBSeslock);
+ read_unlock(&cifs_tcp_ses_lock);
}
}
}
next prev parent reply other threads:[~2008-12-03 20:18 UTC|newest]
Thread overview: 190+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20081203193901.715896543@mini.kroah.org>
2008-12-03 19:47 ` [patch 000/104] 2.6.27-stable review Greg KH
2008-12-03 19:48 ` [patch 001/104] USB: gadget rndis: send notifications Greg KH
2008-12-03 19:48 ` [patch 002/104] USB: gadget rndis: stop windows self-immolation Greg KH
2008-12-03 19:48 ` [patch 003/104] USB: usbmon: fix read(2) Greg KH
2008-12-03 19:48 ` [patch 004/104] USB: fix SB700 usb subsystem hang bug Greg KH
2008-12-03 19:48 ` [patch 005/104] USB: fix SB600 USB " Greg KH
2008-12-03 19:48 ` [patch 006/104] atl1e: fix broken multicast by removing unnecessary crc inversion Greg KH
2008-12-03 19:48 ` [patch 007/104] cpuset: fix regression when failed to generate sched domains Greg KH
2008-12-03 19:48 ` [patch 008/104] cgroups: fix a serious bug in cgroupstats Greg KH
2008-12-03 19:48 ` [patch 009/104] eCryptfs: Allocate up to two scatterlists for crypto ops on keys Greg KH
2008-12-03 19:48 ` [patch 010/104] pxa2xx_spi: bugfix full duplex dma data corruption Greg KH
2008-12-03 19:48 ` [patch 011/104] fbdev: clean the penguins dirty feet Greg KH
2008-12-05 12:58 ` Pavel Machek
2008-12-05 19:29 ` Henrique de Moraes Holschuh
2008-12-06 0:26 ` Greg KH
2008-12-06 2:44 ` Andrew Morton
2008-12-03 19:48 ` [patch 012/104] gpiolib: extend gpio label column width in debugfs file Greg KH
2008-12-03 19:48 ` [patch 013/104] lib/scatterlist.c: fix kunmap() argument in sg_miter_stop() Greg KH
2008-12-03 19:48 ` [patch 014/104] sysvipc: fix the ipc structures initialization Greg KH
2008-12-03 19:48 ` [patch 015/104] parisc: fix kernel crash when unwinding a userspace process Greg KH
2008-12-03 19:48 ` [patch 016/104] epoll: introduce resource usage limits Greg KH
2009-01-23 4:51 ` Bron Gondwana
2009-01-23 5:16 ` Greg KH
2009-01-23 9:47 ` Bron Gondwana
2009-01-23 17:06 ` Greg KH
2009-01-23 17:24 ` Bastien ROUCARIES
2009-01-23 19:36 ` Davide Libenzi
2009-01-24 3:50 ` Bron Gondwana
2009-01-24 8:36 ` Vegard Nossum
2009-01-24 13:03 ` Bron Gondwana
2009-01-25 11:01 ` Bron Gondwana
2009-01-25 12:20 ` Bron Gondwana
2009-01-28 0:35 ` Greg KH
2009-01-28 3:38 ` Bron Gondwana
2009-01-28 3:46 ` Davide Libenzi
2009-01-28 3:57 ` Bron Gondwana
2009-01-28 4:10 ` Davide Libenzi
2009-01-28 5:26 ` Greg KH
2009-01-28 5:36 ` Willy Tarreau
2009-01-28 5:48 ` Davide Libenzi
2009-01-28 6:20 ` Willy Tarreau
2009-01-28 6:36 ` Davide Libenzi
2009-01-28 6:59 ` Willy Tarreau
2009-01-28 6:38 ` Davide Libenzi
2009-01-28 6:52 ` Bron Gondwana
2009-01-28 7:34 ` Davide Libenzi
2009-01-28 10:45 ` Bron Gondwana
2009-01-28 6:57 ` Davide Libenzi
2009-01-28 9:24 ` Bron Gondwana
2009-01-28 16:56 ` Davide Libenzi
2009-01-28 21:46 ` Chris Adams
2009-01-28 23:54 ` Davide Libenzi
2009-01-28 3:47 ` [PATCH 1/3] epoll: increase default max_user_instances to 1024 Bron Gondwana
2009-01-28 4:00 ` Davide Libenzi
2009-01-28 4:07 ` Ray Lee
2009-01-28 4:14 ` Davide Libenzi
2009-01-28 4:55 ` Bron Gondwana
2009-01-28 5:30 ` Davide Libenzi
2009-01-28 5:38 ` Bron Gondwana
2009-01-28 10:16 ` Alan Cox
2009-01-28 10:59 ` Bron Gondwana
2009-01-28 11:36 ` Alan Cox
2009-01-28 13:28 ` Bron Gondwana
2009-01-28 4:39 ` Bron Gondwana
2009-01-28 5:32 ` Bron Gondwana
2009-01-28 11:08 ` Vegard Nossum
2009-01-28 16:52 ` Davide Libenzi
2009-01-28 20:51 ` Bron Gondwana
2009-01-28 23:51 ` Davide Libenzi
2009-01-29 0:28 ` Bron Gondwana
2009-01-28 3:47 ` [PATCH 2/3] epoll: allow 0 for "unlimited" on epoll limits Bron Gondwana
2009-01-28 3:47 ` [PATCH 3/3] epoll: add /proc/sys/fs/epoll/limits interface Bron Gondwana
2009-01-25 12:03 ` [patch 016/104] epoll: introduce resource usage limits Bron Gondwana
2009-01-23 19:28 ` Davide Libenzi
2008-12-03 19:48 ` [patch 017/104] Fix inotify watch removal/umount races Greg KH
2008-12-03 19:48 ` [patch 018/104] IA64: fix boot panic caused by offline CPUs Greg KH
2008-12-03 19:49 ` [patch 019/104] V4L/DVB (9352): Add some missing compat32 ioctls Greg KH
2008-12-03 19:49 ` [patch 020/104] Input: atkbd - add keymap quirk for Inventec Symphony systems Greg KH
2008-12-03 19:49 ` [patch 021/104] lib/idr.c: fix rcu related race with idr_find Greg KH
2008-12-09 21:40 ` Dave Airlie
2008-12-09 22:47 ` Linus Torvalds
2008-12-10 0:43 ` Dave Airlie
2008-12-10 1:46 ` Dave Airlie
2008-12-10 2:02 ` Andrew Morton
2008-12-10 2:08 ` Dave Airlie
2008-12-10 2:32 ` Andrew Morton
2008-12-10 17:33 ` Manfred Spraul
2008-12-03 19:49 ` [patch 022/104] parport_serial: fix array overflow Greg KH
2008-12-03 19:49 ` [patch 023/104] x86: more general identifier for Phoenix BIOS Greg KH
2008-12-03 19:49 ` [patch 024/104] x86: always define DECLARE_PCI_UNMAP* macros Greg KH
2008-12-03 19:49 ` [patch 025/104] ath9k: Fix SW-IOMMU bounce buffer starvation Greg KH
2008-12-03 19:50 ` [patch 026/104] ath9k: correct expected max RX buffer size Greg KH
2008-12-03 19:50 ` [patch 027/104] axnet_cs / pcnet_cs: moving PCMCIA_DEVICE_PROD_ID for Netgear FA411 Greg KH
2008-12-03 22:06 ` Cord Walter
2008-12-03 19:50 ` [patch 028/104] PCI Hotplug core: add name param pci_hp_register interface Greg KH
2008-12-03 19:50 ` [patch 029/104] PCI: update pci_create_slot() to take a hotplug param Greg KH
2008-12-03 19:50 ` [patch 030/104] PCI Hotplug: serialize pci_hp_register and pci_hp_deregister Greg KH
2008-12-03 19:50 ` [patch 031/104] PCI: prevent duplicate slot names Greg KH
2008-12-04 22:10 ` Alex Chiang
2008-12-05 18:27 ` [stable] " Greg KH
2008-12-09 22:41 ` Jesse Barnes
2008-12-03 19:50 ` [patch 032/104] PCI, PCI Hotplug: introduce slot_name helpers Greg KH
2008-12-03 19:50 ` [patch 033/104] PCI: acpiphp: remove name parameter Greg KH
2008-12-03 19:50 ` [patch 034/104] PCI: cpci_hotplug: stop managing hotplug_slot->name Greg KH
2008-12-03 22:15 ` Scott Murray
2008-12-03 19:50 ` [patch 035/104] PCI: cpqphp: " Greg KH
2008-12-03 19:51 ` [patch 036/104] PCI: fakephp: remove name parameter Greg KH
2008-12-03 19:51 ` [patch 037/104] PCI: ibmphp: stop managing hotplug_slot->name Greg KH
2008-12-03 19:51 ` [patch 038/104] PCI: pciehp: remove name parameter Greg KH
2008-12-03 19:51 ` [patch 039/104] PCI: rpaphp: kmalloc/kfree slot->name directly Greg KH
2008-12-03 19:51 ` [patch 040/104] PCI: SGI Hotplug: stop managing bss_hotplug_slot->name Greg KH
2008-12-03 19:51 ` [patch 041/104] PCI: shcphp: remove name parameter Greg KH
2008-12-03 19:51 ` [patch 042/104] PCI: Hotplug core: remove name Greg KH
2008-12-03 19:51 ` [patch 043/104] CPUFREQ: powernow-k8: ignore out-of-range PstateStatus value Greg KH
2008-12-03 19:51 ` [patch 044/104] xen: do not reserve 2 pages of padding between hypervisor and fixmap Greg KH
2008-12-03 19:51 ` [patch 045/104] x86: Hibernate: Fix breakage on x86_32 with CONFIG_NUMA set Greg KH
2008-12-03 19:51 ` [patch 046/104] x86: SB600: skip ACPI IRQ0 override if it is not routed to INT2 of IOAPIC Greg KH
2008-12-03 19:51 ` [patch 047/104] libata: Avoid overflow in libata when tf->hba_lbal > 127 Greg KH
2008-12-03 19:51 ` [patch 048/104] x86: call dmi-quirks for HP Laptops after early-quirks are executed Greg KH
2008-12-03 19:51 ` [patch 049/104] igb: Use device_set_wakeup_enable Greg KH
2008-12-03 19:51 ` [patch 050/104] e1000: " Greg KH
2008-12-03 19:52 ` [patch 051/104] e1000e: " Greg KH
2008-12-03 19:52 ` [patch 052/104] libata: blacklist Seagate drives which time out FLUSH_CACHE when used with NCQ Greg KH
2008-12-03 19:52 ` [patch 053/104] rtl8187: add device ID 0bda:8198 Greg KH
2008-12-03 19:52 ` [patch 054/104] rtl8187: Add USB ID for Belkin F5D7050 with RTL8187B chip Greg KH
2008-12-03 19:52 ` [patch 055/104] cifs: Reduce number of socket retries in large write path Greg KH
2008-12-03 19:52 ` [patch 056/104] cifs: Fix error in smb_send2 Greg KH
2008-12-03 19:52 ` [patch 057/104] powerpc/spufs: Fix spinning in spufs_ps_fault on signal Greg KH
2008-12-03 19:52 ` [patch 058/104] powerpc/spufs: add a missing mutex_unlock Greg KH
2008-12-03 19:52 ` [patch 059/104] WATCHDOG: hpwdt: set the mapped BIOS address space as executable Greg KH
2008-12-03 19:52 ` [patch 060/104] WATCHDOG: hpwdt: Fix kdump when using hpwdt Greg KH
2008-12-03 19:52 ` [patch 061/104] Remove -mno-spe flags as they dont belong Greg KH
2008-12-03 19:53 ` [patch 062/104] ACPI: EC: count interrupts only if called from interrupt handler Greg KH
2008-12-05 13:06 ` Pavel Machek
2008-12-06 0:26 ` Greg KH
2008-12-03 19:53 ` [patch 063/104] ieee1394: sbp2: another iPod mini quirk entry Greg KH
2008-12-03 19:53 ` [patch 064/104] firewire: fw-sbp2: " Greg KH
2008-12-03 19:53 ` [patch 065/104] IB/mlx4: Fix MTT leakage in resize CQ Greg KH
2008-12-03 19:53 ` [patch 066/104] net: Fix soft lockups/OOM issues w/ unix garbage collector (CVE-2008-5300) Greg KH
2008-12-03 19:53 ` [patch 067/104] libata: improve phantom device detection Greg KH
2008-12-04 4:20 ` Tejun Heo
2008-12-05 18:36 ` [stable] " Greg KH
2008-12-06 5:24 ` Tejun Heo
2008-12-03 19:53 ` [patch 068/104] cifs: Fix cifs reconnection flags Greg KH
2008-12-03 19:53 ` [patch 069/104] cifs: remove unused list, add new cifs sock list to prepare for mount/umount fix Greg KH
2008-12-03 19:53 ` [patch 070/104] cifs: clean up server protocol handling Greg KH
2008-12-03 19:53 ` [patch 071/104] cifs: disable sharing session and tcon and add new TCP sharing code Greg KH
2008-12-03 19:53 ` Greg KH [this message]
2008-12-03 19:53 ` [patch 073/104] cifs: minor cleanup to cifs_mount Greg KH
2008-12-03 19:53 ` [patch 074/104] cifs: reinstate sharing of tree connections Greg KH
2008-12-03 19:53 ` [patch 075/104] cifs: Fix build break Greg KH
2008-12-03 19:55 ` [patch 076/104] cifs: Fix check for tcon seal setting and fix oops on failed mount from earlier patch Greg KH
2008-12-03 19:56 ` [patch 077/104] cifs: prevent cifs_writepages() from skipping unwritten pages Greg KH
2008-12-03 19:56 ` [patch 078/104] cifs: fix check for dead tcon in smb_init Greg KH
2008-12-03 19:56 ` [patch 079/104] ext4: Update flex_bg free blocks and free inodes counters when resizing Greg KH
2008-12-03 19:56 ` [patch 080/104] ext4: fix #11321: create /proc/ext4/*/stats more carefully Greg KH
2008-12-03 19:56 ` [patch 081/104] jbd2: fix /proc setup for devices that contain / in their names Greg KH
2008-12-03 19:56 ` [patch 082/104] ext4: add missing unlock in ext4_check_descriptors() on error path Greg KH
2008-12-03 19:56 ` [patch 083/104] ext4: elevate write count for migrate ioctl Greg KH
2008-12-03 19:56 ` [patch 084/104] ext4: Renumber EXT4_IOC_MIGRATE Greg KH
2008-12-03 19:56 ` [patch 085/104] ext4/jbd2: Avoid WARN() messages when failing to write to the superblock Greg KH
2008-12-03 19:56 ` [patch 086/104] ext4: fix initialization of UNINIT bitmap blocks Greg KH
2008-12-04 4:10 ` Theodore Tso
2008-12-05 18:36 ` [stable] " Greg KH
2008-12-03 19:56 ` [patch 087/104] jbd2: abort instead of waiting for nonexistent transaction Greg KH
2008-12-03 19:56 ` [patch 088/104] jbd2: Fix buffer head leak when writing the commit block Greg KH
2008-12-03 19:56 ` [patch 089/104] ext4: fix xattr deadlock Greg KH
2008-12-03 19:56 ` [patch 090/104] ext4: Free ext4_prealloc_space using kmem_cache_free Greg KH
2008-12-03 19:56 ` [patch 091/104] ext4: Do mballoc init before doing filesystem recovery Greg KH
2008-12-03 19:56 ` [patch 092/104] ext4: Fix duplicate entries returned from getdents() system call Greg KH
2008-12-03 19:56 ` [patch 093/104] jbd2: dont give up looking for space so easily in __jbd2_log_wait_for_space Greg KH
2008-12-03 19:56 ` [patch 094/104] ext4: Convert to host order before using the values Greg KH
2008-12-03 19:56 ` [patch 095/104] ext4: wait on all pending commits in ext4_sync_fs() Greg KH
2008-12-03 19:56 ` [patch 096/104] ext4: calculate journal credits correctly Greg KH
2008-12-03 19:56 ` [patch 097/104] ext4: Mark the buffer_heads as dirty and uptodate after prepare_write Greg KH
2008-12-03 19:56 ` [patch 098/104] ext4: add checksum calculation when clearing UNINIT flag in ext4_new_inode Greg KH
2008-12-03 19:56 ` [patch 099/104] ext3: fix ext3_dx_readdir hash collision handling Greg KH
2008-12-03 19:56 ` [patch 100/104] ext3: Fix duplicate entries returned from getdents() system call Greg KH
2008-12-03 19:56 ` [patch 101/104] ext3: dont try to resize if there are no reserved gdt blocks left Greg KH
2008-12-04 22:07 ` Valdis.Kletnieks
2008-12-03 19:56 ` [patch 102/104] ext2: fix ext2 block reservation early ENOSPC issue Greg KH
2008-12-03 19:56 ` [patch 103/104] ext3: fix ext3 " Greg KH
2008-12-03 19:56 ` [patch 104/104] jbd: ordered data integrity fix Greg KH
2008-12-03 21:39 ` [patch 000/104] 2.6.27-stable review Rafael J. Wysocki
2008-12-03 22:10 ` Michael Tokarev
2008-12-03 23:18 ` Rafael J. Wysocki
2008-12-05 0:33 ` Rafael J. Wysocki
2008-12-09 17:58 ` [stable] " Greg KH
2008-12-03 22:06 ` Michael Tokarev
2008-12-03 23:19 ` Greg KH
[not found] <bF63r-1nB-59@gated-at.bofh.it>
[not found] ` <bXmsS-4eW-1@gated-at.bofh.it>
[not found] ` <bXmMj-4HC-7@gated-at.bofh.it>
[not found] ` <bXqQ1-2GV-49@gated-at.bofh.it>
[not found] ` <bXxHH-5zl-23@gated-at.bofh.it>
[not found] ` <bXQqZ-1hm-9@gated-at.bofh.it>
[not found] ` <bYb2q-8bp-21@gated-at.bofh.it>
[not found] ` <bYchR-1AT-3@gated-at.bofh.it>
[not found] ` <bZ6Di-6ZV-1@gated-at.bofh.it>
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20081203195334.GU8950@kroah.com \
--to=gregkh@suse.de \
--cc=akpm@linux-foundation.org \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=cavokz@gmail.com \
--cc=cebbert@redhat.com \
--cc=chuckw@quantumlinux.com \
--cc=davej@redhat.com \
--cc=eteo@redhat.com \
--cc=jake@lwn.net \
--cc=jlayton@redhat.com \
--cc=jmforbes@linuxtx.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mkrufky@linuxtv.org \
--cc=rbranco@la.checkpoint.com \
--cc=rdunlap@xenotime.net \
--cc=reviews@ml.cw.f00f.org \
--cc=sfrench@us.ibm.com \
--cc=sjayaraman@suse.de \
--cc=smfrench@gmail.com \
--cc=stable@kernel.org \
--cc=torvalds@linux-foundation.org \
--cc=tytso@mit.edu \
--cc=w@1wt.eu \
--cc=zwane@arm.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox