From 3eb9a8893a76cf1cda3b41c3212eb2cfe83eae0e Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Wed, 1 Sep 2010 17:06:02 -0700 Subject: cifs: Allow binding to local IP address. When using multi-homed machines, it's nice to be able to specify the local IP to use for outbound connections. This patch gives cifs the ability to bind to a particular IP address. Usage: mount -t cifs -o srcaddr=192.168.1.50,user=foo, ... Usage: mount -t cifs -o srcaddr=2002::100:1,user=foo, ... Acked-by: Jeff Layton Acked-by: Dr. David Holder Signed-off-by: Ben Greear Signed-off-by: Steve French --- fs/cifs/cifsfs.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'fs/cifs/cifsfs.c') diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index b7431afdd76d..1b6ddd6f760f 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "cifsfs.h" #include "cifspdu.h" #define DECLARE_GLOBALS_HERE @@ -367,6 +368,8 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m) { struct cifs_sb_info *cifs_sb = CIFS_SB(m->mnt_sb); struct cifsTconInfo *tcon = cifs_sb->tcon; + struct sockaddr *srcaddr; + srcaddr = (struct sockaddr *)&tcon->ses->server->srcaddr; seq_printf(s, ",unc=%s", tcon->treeName); if (tcon->ses->userName) @@ -374,6 +377,22 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m) if (tcon->ses->domainName) seq_printf(s, ",domain=%s", tcon->ses->domainName); + if (srcaddr->sa_family != AF_UNSPEC) { + struct sockaddr_in *saddr4; + struct sockaddr_in6 *saddr6; + saddr4 = (struct sockaddr_in *)srcaddr; + saddr6 = (struct sockaddr_in6 *)srcaddr; + if (srcaddr->sa_family == AF_INET6) + seq_printf(s, ",srcaddr=%pI6c", + &saddr6->sin6_addr); + else if (srcaddr->sa_family == AF_INET) + seq_printf(s, ",srcaddr=%pI4", + &saddr4->sin_addr.s_addr); + else + seq_printf(s, ",srcaddr=BAD-AF:%i", + (int)(srcaddr->sa_family)); + } + seq_printf(s, ",uid=%d", cifs_sb->mnt_uid); if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) seq_printf(s, ",forceuid"); -- cgit v1.2.3-59-g8ed1b From 736a33205969c16f81d747db14ff4c0f133609a6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 30 Jul 2010 14:56:00 +0200 Subject: cifs: add "mfsymlinks" mount option This is the start for an implementation of "Minshall+French Symlinks" (see http://wiki.samba.org/index.php/UNIX_Extensions#Minshall.2BFrench_symlinks). Signed-off-by: Stefan Metzmacher Signed-off-by: Steve French --- fs/cifs/README | 5 +++++ fs/cifs/cifsfs.c | 2 ++ fs/cifs/connect.c | 11 +++++++++++ 3 files changed, 18 insertions(+) (limited to 'fs/cifs/cifsfs.c') diff --git a/fs/cifs/README b/fs/cifs/README index 7099a526f775..ee68d1036544 100644 --- a/fs/cifs/README +++ b/fs/cifs/README @@ -527,6 +527,11 @@ A partial list of the supported mount options follows: SFU does). In the future the bottom 9 bits of the mode also will be emulated using queries of the security descriptor (ACL). + mfsymlinks Enable support for Minshall+French symlinks + (see http://wiki.samba.org/index.php/UNIX_Extensions#Minshall.2BFrench_symlinks) + This option is ignored when specified together with the + 'sfu' option. Minshall+French symlinks are used even if + the server supports the CIFS Unix Extensions. sign Must use packet signing (helps avoid unwanted data modification by intermediate systems in the route). Note that signing does not work with lanman or plaintext authentication. diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 1b6ddd6f760f..52e89ea07458 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -441,6 +441,8 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m) seq_printf(s, ",dynperm"); if (m->mnt_sb->s_flags & MS_POSIXACL) seq_printf(s, ",acl"); + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) + seq_printf(s, ",mfsymlinks"); seq_printf(s, ",rsize=%d", cifs_sb->rsize); seq_printf(s, ",wsize=%d", cifs_sb->wsize); diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index fa884520fb84..435b912f5de5 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -100,6 +100,7 @@ struct smb_vol { bool noautotune:1; bool nostrictsync:1; /* do not force expensive SMBflush on every sync */ bool fsc:1; /* enable fscache */ + bool mfsymlinks:1; /* use Minshall+French Symlinks */ unsigned int rsize; unsigned int wsize; bool sockopt_tcp_nodelay:1; @@ -1342,6 +1343,8 @@ cifs_parse_mount_options(char *options, const char *devname, "/proc/fs/cifs/LookupCacheEnabled to 0\n"); } else if (strnicmp(data, "fsc", 3) == 0) { vol->fsc = true; + } else if (strnicmp(data, "mfsymlinks", 10) == 0) { + vol->mfsymlinks = true; } else printk(KERN_WARNING "CIFS: Unknown mount option %s\n", data); @@ -2554,6 +2557,14 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info, cFYI(1, "mounting share using direct i/o"); cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; } + if (pvolume_info->mfsymlinks) { + if (pvolume_info->sfu_emul) { + cERROR(1, "mount option mfsymlinks ignored if sfu " + "mount option is used"); + } else { + cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MF_SYMLINKS; + } + } if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm)) cERROR(1, "mount option dynperm ignored if cifsacl " -- cgit v1.2.3-59-g8ed1b From d3bf5221d3274b5015ad18a55060b074cca8d2f0 Mon Sep 17 00:00:00 2001 From: Steve French Date: Wed, 22 Sep 2010 19:15:36 +0000 Subject: [CIFS] Fix ordering of cleanup on module init failure If registering fs cache failed, we weren't cleaning up proc. Acked-by: Jeff Layton CC: Suresh Jayaraman Signed-off-by: Steve French --- fs/cifs/cifsfs.c | 18 +++++++++--------- fs/cifs/connect.c | 1 - 2 files changed, 9 insertions(+), 10 deletions(-) (limited to 'fs/cifs/cifsfs.c') diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 52e89ea07458..eeb8c67a3f29 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -933,11 +933,11 @@ init_cifs(void) rc = cifs_fscache_register(); if (rc) - goto out; + goto out_clean_proc; rc = cifs_init_inodecache(); if (rc) - goto out_clean_proc; + goto out_unreg_fscache; rc = cifs_init_mids(); if (rc) @@ -959,19 +959,19 @@ init_cifs(void) return 0; #ifdef CONFIG_CIFS_UPCALL - out_unregister_filesystem: +out_unregister_filesystem: unregister_filesystem(&cifs_fs_type); #endif - out_destroy_request_bufs: +out_destroy_request_bufs: cifs_destroy_request_bufs(); - out_destroy_mids: +out_destroy_mids: cifs_destroy_mids(); - out_destroy_inodecache: +out_destroy_inodecache: cifs_destroy_inodecache(); - out_clean_proc: - cifs_proc_clean(); +out_unreg_fscache: cifs_fscache_unregister(); - out: +out_clean_proc: + cifs_proc_clean(); return rc; } diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 271038b6ec0e..230410e0a453 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -47,7 +47,6 @@ #include "ntlmssp.h" #include "nterr.h" #include "rfc1002pdu.h" -#include "cn_cifs.h" #include "fscache.h" #define CIFS_PORT 445 -- cgit v1.2.3-59-g8ed1b From ba00ba64cf0895e4c2ac507e56306363dc125a90 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 20 Sep 2010 16:01:31 -0700 Subject: cifs: make various routines use the cifsFileInfo->tcon pointer ...where it's available and appropriate. Signed-off-by: Jeff Layton Signed-off-by: Steve French --- fs/cifs/cifsfs.c | 4 ++-- fs/cifs/file.c | 39 ++++++++++++++++----------------------- fs/cifs/inode.c | 22 ++++++++++++++++------ fs/cifs/ioctl.c | 17 +++-------------- fs/cifs/readdir.c | 19 ++++++++----------- 5 files changed, 45 insertions(+), 56 deletions(-) (limited to 'fs/cifs/cifsfs.c') diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index eeb8c67a3f29..7193494efc03 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -589,6 +589,7 @@ static int cifs_setlease(struct file *file, long arg, struct file_lock **lease) /* note that this is called by vfs setlease with the BKL held although I doubt that BKL is needed here in cifs */ struct inode *inode = file->f_path.dentry->d_inode; + struct cifsFileInfo *cfile = file->private_data; if (!(S_ISREG(inode->i_mode))) return -EINVAL; @@ -599,8 +600,7 @@ static int cifs_setlease(struct file *file, long arg, struct file_lock **lease) ((arg == F_WRLCK) && (CIFS_I(inode)->clientCanCacheAll))) return generic_setlease(file, arg, lease); - else if (CIFS_SB(inode->i_sb)->tcon->local_lease && - !CIFS_I(inode)->clientCanCacheRead) + else if (cfile->tcon->local_lease && !CIFS_I(inode)->clientCanCacheRead) /* If the server claims to support oplock on this file, then we still need to check oplock even if the local_lease mount option is set, but there diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 60061b9c2f67..84979fc77862 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -461,7 +461,7 @@ static int cifs_reopen_file(struct file *file, bool can_flush) } cifs_sb = CIFS_SB(inode->i_sb); - tcon = cifs_sb->tcon; + tcon = pCifsFile->tcon; /* can not grab rename sem here because various ops, including those that already have the rename sem can end up causing writepage @@ -575,7 +575,7 @@ int cifs_close(struct inode *inode, struct file *file) xid = GetXid(); cifs_sb = CIFS_SB(inode->i_sb); - pTcon = cifs_sb->tcon; + pTcon = pSMBFile->tcon; if (pSMBFile) { struct cifsLockInfo *li, *tmp; write_lock(&GlobalSMBSeslock); @@ -653,11 +653,7 @@ int cifs_closedir(struct inode *inode, struct file *file) xid = GetXid(); if (pCFileStruct) { - struct cifsTconInfo *pTcon; - struct cifs_sb_info *cifs_sb = - CIFS_SB(file->f_path.dentry->d_sb); - - pTcon = cifs_sb->tcon; + struct cifsTconInfo *pTcon = pCFileStruct->tcon; cFYI(1, "Freeing private data in close dir"); write_lock(&GlobalSMBSeslock); @@ -767,7 +763,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) cFYI(1, "Unknown type of lock"); cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); - tcon = cifs_sb->tcon; + tcon = ((struct cifsFileInfo *)file->private_data)->tcon; if (file->private_data == NULL) { rc = -EBADF; @@ -960,14 +956,14 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); - pTcon = cifs_sb->tcon; - /* cFYI(1, " write %d bytes to offset %lld of %s", write_size, *poffset, file->f_path.dentry->d_name.name); */ if (file->private_data == NULL) return -EBADF; + open_file = file->private_data; + pTcon = open_file->tcon; rc = generic_write_checks(file, poffset, &write_size, 0); if (rc) @@ -1062,14 +1058,13 @@ static ssize_t cifs_write(struct file *file, const char *write_data, cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); - pTcon = cifs_sb->tcon; - cFYI(1, "write %zd bytes to offset %lld of %s", write_size, *poffset, file->f_path.dentry->d_name.name); if (file->private_data == NULL) return -EBADF; open_file = file->private_data; + pTcon = open_file->tcon; xid = GetXid(); @@ -1284,7 +1279,6 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) int rc = -EFAULT; int bytes_written = 0; struct cifs_sb_info *cifs_sb; - struct cifsTconInfo *pTcon; struct inode *inode; struct cifsFileInfo *open_file; @@ -1293,7 +1287,6 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) inode = page->mapping->host; cifs_sb = CIFS_SB(inode->i_sb); - pTcon = cifs_sb->tcon; offset += (loff_t)from; write_data = kmap(page); @@ -1352,6 +1345,7 @@ static int cifs_writepages(struct address_space *mapping, int nr_pages; __u64 offset = 0; struct cifsFileInfo *open_file; + struct cifsTconInfo *tcon; struct cifsInodeInfo *cifsi = CIFS_I(mapping->host); struct page *page; struct pagevec pvec; @@ -1501,8 +1495,9 @@ retry: cERROR(1, "No writable handles for inode"); rc = -EBADF; } else { + tcon = open_file->tcon; long_op = cifs_write_timeout(cifsi, offset); - rc = CIFSSMBWrite2(xid, cifs_sb->tcon, + rc = CIFSSMBWrite2(xid, tcon, open_file->netfid, bytes_to_write, offset, &bytes_written, iov, n_iov, @@ -1520,8 +1515,7 @@ retry: else set_bit(AS_EIO, &mapping->flags); } else { - cifs_stats_bytes_written(cifs_sb->tcon, - bytes_written); + cifs_stats_bytes_written(tcon, bytes_written); } } for (i = 0; i < n_iov; i++) { @@ -1665,7 +1659,7 @@ int cifs_fsync(struct file *file, int datasync) if (rc == 0) { rc = CIFS_I(inode)->write_behind_rc; CIFS_I(inode)->write_behind_rc = 0; - tcon = CIFS_SB(inode->i_sb)->tcon; + tcon = smbfile->tcon; if (!rc && tcon && smbfile && !(CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) rc = CIFSSMBFlush(xid, tcon, smbfile->netfid); @@ -1750,7 +1744,6 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, xid = GetXid(); cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); - pTcon = cifs_sb->tcon; if (file->private_data == NULL) { rc = -EBADF; @@ -1758,6 +1751,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, return rc; } open_file = file->private_data; + pTcon = open_file->tcon; if ((file->f_flags & O_ACCMODE) == O_WRONLY) cFYI(1, "attempting read on write only file instance"); @@ -1831,7 +1825,6 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, xid = GetXid(); cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); - pTcon = cifs_sb->tcon; if (file->private_data == NULL) { rc = -EBADF; @@ -1839,6 +1832,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, return rc; } open_file = file->private_data; + pTcon = open_file->tcon; if ((file->f_flags & O_ACCMODE) == O_WRONLY) cFYI(1, "attempting read on write only file instance"); @@ -1974,7 +1968,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, } open_file = file->private_data; cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); - pTcon = cifs_sb->tcon; + pTcon = open_file->tcon; /* * Reads as many pages as possible from fscache. Returns -ENOBUFS @@ -2312,7 +2306,6 @@ void cifs_oplock_break(struct work_struct *work) oplock_break); struct inode *inode = cfile->pInode; struct cifsInodeInfo *cinode = CIFS_I(inode); - struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->mnt->mnt_sb); int rc, waitrc = 0; if (inode && S_ISREG(inode->i_mode)) { @@ -2339,7 +2332,7 @@ void cifs_oplock_break(struct work_struct *work) * disconnected since oplock already released by the server */ if (!cfile->closePend && !cfile->oplock_break_cancelled) { - rc = CIFSSMBLock(0, cifs_sb->tcon, cfile->netfid, 0, 0, 0, 0, + rc = CIFSSMBLock(0, cfile->tcon, cfile->netfid, 0, 0, 0, 0, LOCKING_ANDX_OPLOCK_RELEASE, false); cFYI(1, "Oplock release rc = %d", rc); } diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 016975b8e6dd..0fa145596fcf 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -288,8 +288,8 @@ int cifs_get_file_info_unix(struct file *filp) struct cifs_fattr fattr; struct inode *inode = filp->f_path.dentry->d_inode; struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); - struct cifsTconInfo *tcon = cifs_sb->tcon; struct cifsFileInfo *cfile = filp->private_data; + struct cifsTconInfo *tcon = cfile->tcon; xid = GetXid(); rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data); @@ -522,8 +522,8 @@ int cifs_get_file_info(struct file *filp) struct cifs_fattr fattr; struct inode *inode = filp->f_path.dentry->d_inode; struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); - struct cifsTconInfo *tcon = cifs_sb->tcon; struct cifsFileInfo *cfile = filp->private_data; + struct cifsTconInfo *tcon = cfile->tcon; xid = GetXid(); rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data); @@ -891,7 +891,7 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid, struct cifsFileInfo *open_file; struct cifsInodeInfo *cifsInode = CIFS_I(inode); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); - struct cifsTconInfo *pTcon = cifs_sb->tcon; + struct cifsTconInfo *pTcon; FILE_BASIC_INFO info_buf; if (attrs == NULL) @@ -934,9 +934,12 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid, if (open_file) { netfid = open_file->netfid; netpid = open_file->pid; + pTcon = open_file->tcon; goto set_via_filehandle; } + pTcon = cifs_sb->tcon; + /* * NT4 apparently returns success on this call, but it doesn't * really work. @@ -1611,11 +1614,12 @@ int cifs_revalidate_file(struct file *filp) { int rc = 0; struct inode *inode = filp->f_path.dentry->d_inode; + struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data; if (!cifs_inode_needs_reval(inode)) goto check_inval; - if (CIFS_SB(inode->i_sb)->tcon->unix_ext) + if (cfile->tcon->unix_ext) rc = cifs_get_file_info_unix(filp); else rc = cifs_get_file_info(filp); @@ -1720,7 +1724,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs, struct cifsFileInfo *open_file; struct cifsInodeInfo *cifsInode = CIFS_I(inode); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); - struct cifsTconInfo *pTcon = cifs_sb->tcon; + struct cifsTconInfo *pTcon = NULL; /* * To avoid spurious oplock breaks from server, in the case of @@ -1735,6 +1739,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs, if (open_file) { __u16 nfid = open_file->netfid; __u32 npid = open_file->pid; + pTcon = open_file->tcon; rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid, npid, false); cifsFileInfo_put(open_file); @@ -1749,6 +1754,9 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs, rc = -EINVAL; if (rc != 0) { + if (pTcon == NULL) + pTcon = cifs_sb->tcon; + /* Set file size by pathname rather than by handle either because no valid, writeable file handle for it was found or because there was an error setting @@ -1798,7 +1806,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) struct inode *inode = direntry->d_inode; struct cifsInodeInfo *cifsInode = CIFS_I(inode); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); - struct cifsTconInfo *pTcon = cifs_sb->tcon; + struct cifsTconInfo *pTcon; struct cifs_unix_set_info_args *args = NULL; struct cifsFileInfo *open_file; @@ -1889,9 +1897,11 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) if (open_file) { u16 nfid = open_file->netfid; u32 npid = open_file->pid; + pTcon = open_file->tcon; rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid); cifsFileInfo_put(open_file); } else { + pTcon = cifs_sb->tcon; rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c index 9d38a71c8e14..cc70a61a47d2 100644 --- a/fs/cifs/ioctl.c +++ b/fs/cifs/ioctl.c @@ -37,11 +37,11 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) int xid; struct cifs_sb_info *cifs_sb; #ifdef CONFIG_CIFS_POSIX + struct cifsFileInfo *pSMBFile = filep->private_data; + struct cifsTconInfo *tcon = pSMBFile->tcon; __u64 ExtAttrBits = 0; __u64 ExtAttrMask = 0; - __u64 caps; - struct cifsTconInfo *tcon; - struct cifsFileInfo *pSMBFile = filep->private_data; + __u64 caps = le64_to_cpu(tcon->fsUnixInfo.Capability); #endif /* CONFIG_CIFS_POSIX */ xid = GetXid(); @@ -50,17 +50,6 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) cifs_sb = CIFS_SB(inode->i_sb); -#ifdef CONFIG_CIFS_POSIX - tcon = cifs_sb->tcon; - if (tcon) - caps = le64_to_cpu(tcon->fsUnixInfo.Capability); - else { - rc = -EIO; - FreeXid(xid); - return -EIO; - } -#endif /* CONFIG_CIFS_POSIX */ - switch (command) { case CIFS_IOC_CHECKUMOUNT: cFYI(1, "User unmount attempted"); diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 6a8b417babab..d7784a95134f 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -228,22 +228,21 @@ static int initiate_cifs_search(const int xid, struct file *file) struct cifs_sb_info *cifs_sb; struct cifsTconInfo *pTcon; - if (file->private_data == NULL) { + cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); + if (cifs_sb == NULL) + return -EINVAL; + + if (file->private_data == NULL) file->private_data = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); - } if (file->private_data == NULL) return -ENOMEM; cifsFile = file->private_data; cifsFile->invalidHandle = true; cifsFile->srch_inf.endOfSearch = false; - - cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); - if (cifs_sb == NULL) - return -EINVAL; - - pTcon = cifs_sb->tcon; + cifsFile->tcon = cifs_sb->tcon; + pTcon = cifsFile->tcon; if (pTcon == NULL) return -EINVAL; @@ -786,9 +785,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) xid = GetXid(); cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); - pTcon = cifs_sb->tcon; - if (pTcon == NULL) - return -EINVAL; switch ((int) file->f_pos) { case 0: @@ -838,6 +834,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) CIFSFindClose(xid, pTcon, cifsFile->netfid); } */ + pTcon = cifsFile->tcon; rc = find_cifs_entry(xid, pTcon, file, ¤t_entry, &num_to_fill); if (rc) { -- cgit v1.2.3-59-g8ed1b From a6e8a8455c94565c53e1a1756d2ab9d9e3a902b8 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 20 Sep 2010 16:01:33 -0700 Subject: cifs: add function to get a tcon from cifs_sb When we convert cifs to do multiple sessions per mount, we'll need more than one tcon per superblock. At that point "cifs_sb->tcon" will make no sense. Add a new accessor function that gets a tcon given a cifs_sb. For now, it just returns cifs_sb->tcon. Later it'll do more. Signed-off-by: Jeff Layton Signed-off-by: Steve French --- fs/cifs/cifs_dfs_ref.c | 2 +- fs/cifs/cifsacl.c | 16 ++++++++-------- fs/cifs/cifsfs.c | 11 +++-------- fs/cifs/cifsglob.h | 6 ++++++ fs/cifs/connect.c | 4 ++-- fs/cifs/dir.c | 20 ++++++++++---------- fs/cifs/file.c | 4 ++-- fs/cifs/fscache.c | 7 ++++--- fs/cifs/inode.c | 49 +++++++++++++++++++++++++------------------------ fs/cifs/link.c | 8 ++++---- fs/cifs/misc.c | 2 +- fs/cifs/readdir.c | 8 ++++---- fs/cifs/xattr.c | 8 ++++---- 13 files changed, 74 insertions(+), 71 deletions(-) (limited to 'fs/cifs/cifsfs.c') diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c index d6ced7aa23cf..f1e13ea45a17 100644 --- a/fs/cifs/cifs_dfs_ref.c +++ b/fs/cifs/cifs_dfs_ref.c @@ -316,7 +316,7 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) nd->path.dentry = dget(dentry); cifs_sb = CIFS_SB(dentry->d_inode->i_sb); - ses = cifs_sb->tcon->ses; + ses = cifs_sb_tcon(cifs_sb)->ses; if (!ses) { rc = -EINVAL; diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index 85d7cf7ff2c8..32f244909a0d 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c @@ -559,7 +559,7 @@ static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, int xid, rc; xid = GetXid(); - rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen); + rc = CIFSSMBGetCIFSACL(xid, cifs_sb_tcon(cifs_sb), fid, &pntsd, pacllen); FreeXid(xid); @@ -577,7 +577,7 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, xid = GetXid(); - rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, READ_CONTROL, 0, + rc = CIFSSMBOpen(xid, cifs_sb_tcon(cifs_sb), path, FILE_OPEN, READ_CONTROL, 0, &fid, &oplock, NULL, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (rc) { @@ -585,10 +585,10 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, goto out; } - rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen); + rc = CIFSSMBGetCIFSACL(xid, cifs_sb_tcon(cifs_sb), fid, &pntsd, pacllen); cFYI(1, "GetCIFSACL rc = %d ACL len %d", rc, *pacllen); - CIFSSMBClose(xid, cifs_sb->tcon, fid); + CIFSSMBClose(xid, cifs_sb_tcon(cifs_sb), fid); out: FreeXid(xid); return pntsd; @@ -618,7 +618,7 @@ static int set_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, __u16 fid, int xid, rc; xid = GetXid(); - rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen); + rc = CIFSSMBSetCIFSACL(xid, cifs_sb_tcon(cifs_sb), fid, pnntsd, acllen); FreeXid(xid); cFYI(DBG2, "SetCIFSACL rc = %d", rc); @@ -634,7 +634,7 @@ static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path, xid = GetXid(); - rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, WRITE_DAC, 0, + rc = CIFSSMBOpen(xid, cifs_sb_tcon(cifs_sb), path, FILE_OPEN, WRITE_DAC, 0, &fid, &oplock, NULL, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (rc) { @@ -642,10 +642,10 @@ static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path, goto out; } - rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen); + rc = CIFSSMBSetCIFSACL(xid, cifs_sb_tcon(cifs_sb), fid, pnntsd, acllen); cFYI(DBG2, "SetCIFSACL rc = %d", rc); - CIFSSMBClose(xid, cifs_sb->tcon, fid); + CIFSSMBClose(xid, cifs_sb_tcon(cifs_sb), fid); out: FreeXid(xid); return rc; diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 7193494efc03..b9624abb7261 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -137,9 +137,6 @@ cifs_read_super(struct super_block *sb, void *data, sb->s_magic = CIFS_MAGIC_NUMBER; sb->s_op = &cifs_super_ops; sb->s_bdi = &cifs_sb->bdi; -/* if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512) - sb->s_blocksize = - cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */ sb->s_blocksize = CIFS_MAX_MSGSIZE; sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */ inode = cifs_root_iget(sb, ROOT_I); @@ -225,7 +222,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf) { struct super_block *sb = dentry->d_sb; struct cifs_sb_info *cifs_sb = CIFS_SB(sb); - struct cifsTconInfo *tcon = cifs_sb->tcon; + struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb); int rc = -EOPNOTSUPP; int xid; @@ -367,7 +364,7 @@ static int cifs_show_options(struct seq_file *s, struct vfsmount *m) { struct cifs_sb_info *cifs_sb = CIFS_SB(m->mnt_sb); - struct cifsTconInfo *tcon = cifs_sb->tcon; + struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb); struct sockaddr *srcaddr; srcaddr = (struct sockaddr *)&tcon->ses->server->srcaddr; @@ -458,9 +455,7 @@ static void cifs_umount_begin(struct super_block *sb) if (cifs_sb == NULL) return; - tcon = cifs_sb->tcon; - if (tcon == NULL) - return; + tcon = cifs_sb_tcon(cifs_sb); read_lock(&cifs_tcp_ses_lock); if ((tcon->tc_count > 1) || (tcon->tidStatus == CifsExiting)) { diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 6f3968a5fea4..c3510168438e 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -413,6 +413,12 @@ CIFS_SB(struct super_block *sb) return sb->s_fs_info; } +static inline struct cifsTconInfo * +cifs_sb_tcon(struct cifs_sb_info *cifs_sb) +{ + return cifs_sb->tcon; +} + static inline char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb) { if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 230410e0a453..c42d37fb5b7c 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -3026,8 +3026,8 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) int rc = 0; char *tmp; - if (cifs_sb->tcon) - cifs_put_tcon(cifs_sb->tcon); + if (cifs_sb_tcon(cifs_sb)) + cifs_put_tcon(cifs_sb_tcon(cifs_sb)); cifs_sb->tcon = NULL; tmp = cifs_sb->prepath; diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 613589cf5172..f660a15eb14f 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -64,8 +64,8 @@ build_path_from_dentry(struct dentry *direntry) cifs_sb = CIFS_SB(direntry->d_sb); dirsep = CIFS_DIR_SEP(cifs_sb); pplen = cifs_sb->prepathlen; - if (cifs_sb->tcon && (cifs_sb->tcon->Flags & SMB_SHARE_IS_IN_DFS)) - dfsplen = strnlen(cifs_sb->tcon->treeName, MAX_TREE_SIZE + 1); + if (cifs_sb_tcon(cifs_sb) && (cifs_sb_tcon(cifs_sb)->Flags & SMB_SHARE_IS_IN_DFS)) + dfsplen = strnlen(cifs_sb_tcon(cifs_sb)->treeName, MAX_TREE_SIZE + 1); else dfsplen = 0; cifs_bp_rename_retry: @@ -117,7 +117,7 @@ cifs_bp_rename_retry: /* BB test paths to Windows with '/' in the midst of prepath */ if (dfsplen) { - strncpy(full_path, cifs_sb->tcon->treeName, dfsplen); + strncpy(full_path, cifs_sb_tcon(cifs_sb)->treeName, dfsplen); if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) { int i; for (i = 0; i < dfsplen; i++) { @@ -150,7 +150,7 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, pCifsFile->pfile = file; pCifsFile->invalidHandle = false; pCifsFile->closePend = false; - pCifsFile->tcon = cifs_sb->tcon; + pCifsFile->tcon = cifs_sb_tcon(cifs_sb); mutex_init(&pCifsFile->fh_mutex); mutex_init(&pCifsFile->lock_mutex); INIT_LIST_HEAD(&pCifsFile->llist); @@ -158,7 +158,7 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, INIT_WORK(&pCifsFile->oplock_break, cifs_oplock_break); write_lock(&GlobalSMBSeslock); - list_add(&pCifsFile->tlist, &cifs_sb->tcon->openFileList); + list_add(&pCifsFile->tlist, &cifs_sb_tcon(cifs_sb)->openFileList); pCifsInode = CIFS_I(newinode); if (pCifsInode) { /* if readable file instance put first in list*/ @@ -225,7 +225,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode, posix_flags |= SMB_O_DIRECT; mode &= ~current_umask(); - rc = CIFSPOSIXCreate(xid, cifs_sb->tcon, posix_flags, mode, + rc = CIFSPOSIXCreate(xid, cifs_sb_tcon(cifs_sb), posix_flags, mode, pnetfid, presp_data, poplock, full_path, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); @@ -298,7 +298,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, xid = GetXid(); cifs_sb = CIFS_SB(inode->i_sb); - tcon = cifs_sb->tcon; + tcon = cifs_sb_tcon(cifs_sb); full_path = build_path_from_dentry(direntry); if (full_path == NULL) { @@ -373,7 +373,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, if (!tcon->unix_ext && (mode & S_IWUGO) == 0) create_options |= CREATE_OPTION_READONLY; - if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS) + if (tcon->ses->capabilities & CAP_NT_SMBS) rc = CIFSSMBOpen(xid, tcon, full_path, disposition, desiredAccess, create_options, &fileHandle, &oplock, buf, cifs_sb->local_nls, @@ -504,7 +504,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, xid = GetXid(); cifs_sb = CIFS_SB(inode->i_sb); - pTcon = cifs_sb->tcon; + pTcon = cifs_sb_tcon(cifs_sb); full_path = build_path_from_dentry(direntry); if (full_path == NULL) { @@ -631,7 +631,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, /* check whether path exists */ cifs_sb = CIFS_SB(parent_dir_inode->i_sb); - pTcon = cifs_sb->tcon; + pTcon = cifs_sb_tcon(cifs_sb); /* * Don't allow the separator character in a path component. diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 84979fc77862..6712c2b0a0ae 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -235,7 +235,7 @@ int cifs_open(struct inode *inode, struct file *file) xid = GetXid(); cifs_sb = CIFS_SB(inode->i_sb); - tcon = cifs_sb->tcon; + tcon = cifs_sb_tcon(cifs_sb); pCifsInode = CIFS_I(file->f_path.dentry->d_inode); @@ -345,7 +345,7 @@ int cifs_open(struct inode *inode, struct file *file) goto out; } - if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS) + if (tcon->ses->capabilities & CAP_NT_SMBS) rc = CIFSSMBOpen(xid, tcon, full_path, disposition, desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c index 9f3f5c4be161..ec4318b019cc 100644 --- a/fs/cifs/fscache.c +++ b/fs/cifs/fscache.c @@ -66,11 +66,11 @@ static void cifs_fscache_enable_inode_cookie(struct inode *inode) if (cifsi->fscache) return; - cifsi->fscache = fscache_acquire_cookie(cifs_sb->tcon->fscache, + cifsi->fscache = fscache_acquire_cookie(cifs_sb_tcon(cifs_sb)->fscache, &cifs_fscache_inode_object_def, cifsi); cFYI(1, "CIFS: got FH cookie (0x%p/0x%p)", - cifs_sb->tcon->fscache, cifsi->fscache); + cifs_sb_tcon(cifs_sb)->fscache, cifsi->fscache); } void cifs_fscache_release_inode_cookie(struct inode *inode) @@ -117,7 +117,8 @@ void cifs_fscache_reset_inode_cookie(struct inode *inode) /* retire the current fscache cache and get a new one */ fscache_relinquish_cookie(cifsi->fscache, 1); - cifsi->fscache = fscache_acquire_cookie(cifs_sb->tcon->fscache, + cifsi->fscache = fscache_acquire_cookie( + cifs_sb_tcon(cifs_sb)->fscache, &cifs_fscache_inode_object_def, cifsi); cFYI(1, "CIFS: new cookie 0x%p oldcookie 0x%p", diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 0fa145596fcf..dce2d598927e 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -52,7 +52,7 @@ static void cifs_set_ops(struct inode *inode, const bool is_dfs_referral) /* check if server can support readpages */ - if (cifs_sb->tcon->ses->server->maxBuf < + if (cifs_sb_tcon(cifs_sb)->ses->server->maxBuf < PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE) inode->i_data.a_ops = &cifs_addr_ops_smallbuf; else @@ -315,7 +315,8 @@ int cifs_get_inode_info_unix(struct inode **pinode, struct cifsTconInfo *tcon; struct cifs_sb_info *cifs_sb = CIFS_SB(sb); - tcon = cifs_sb->tcon; + tcon = cifs_sb_tcon(cifs_sb); + cFYI(1, "Getting info on %s", full_path); /* could have done a find first instead but this returns more info */ @@ -360,7 +361,7 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path, int rc; int oplock = 0; __u16 netfid; - struct cifsTconInfo *pTcon = cifs_sb->tcon; + struct cifsTconInfo *pTcon = cifs_sb_tcon(cifs_sb); char buf[24]; unsigned int bytes_read; char *pbuf; @@ -449,7 +450,7 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path, char ea_value[4]; __u32 mode; - rc = CIFSSMBQAllEAs(xid, cifs_sb->tcon, path, "SETFILEBITS", + rc = CIFSSMBQAllEAs(xid, cifs_sb_tcon(cifs_sb), path, "SETFILEBITS", ea_value, 4 /* size of buf */, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); @@ -489,8 +490,8 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime); if (adjust_tz) { - fattr->cf_ctime.tv_sec += cifs_sb->tcon->ses->server->timeAdj; - fattr->cf_mtime.tv_sec += cifs_sb->tcon->ses->server->timeAdj; + fattr->cf_ctime.tv_sec += cifs_sb_tcon(cifs_sb)->ses->server->timeAdj; + fattr->cf_mtime.tv_sec += cifs_sb_tcon(cifs_sb)->ses->server->timeAdj; } fattr->cf_eof = le64_to_cpu(info->EndOfFile); @@ -566,7 +567,7 @@ int cifs_get_inode_info(struct inode **pinode, bool adjustTZ = false; struct cifs_fattr fattr; - pTcon = cifs_sb->tcon; + pTcon = cifs_sb_tcon(cifs_sb); cFYI(1, "Getting info on %s", full_path); if ((pfindData == NULL) && (*pinode != NULL)) { @@ -706,8 +707,8 @@ char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb) return full_path; } - if (cifs_sb->tcon && (cifs_sb->tcon->Flags & SMB_SHARE_IS_IN_DFS)) - dfsplen = strnlen(cifs_sb->tcon->treeName, MAX_TREE_SIZE + 1); + if (cifs_sb_tcon(cifs_sb) && (cifs_sb_tcon(cifs_sb)->Flags & SMB_SHARE_IS_IN_DFS)) + dfsplen = strnlen(cifs_sb_tcon(cifs_sb)->treeName, MAX_TREE_SIZE + 1); else dfsplen = 0; @@ -716,7 +717,7 @@ char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb) return full_path; if (dfsplen) { - strncpy(full_path, cifs_sb->tcon->treeName, dfsplen); + strncpy(full_path, cifs_sb_tcon(cifs_sb)->treeName, dfsplen); /* switch slash direction in prepath depending on whether * windows or posix style path names */ @@ -841,7 +842,7 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino) return ERR_PTR(-ENOMEM); xid = GetXid(); - if (cifs_sb->tcon->unix_ext) + if (cifs_sb_tcon(cifs_sb)->unix_ext) rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid); else rc = cifs_get_inode_info(&inode, full_path, NULL, sb, @@ -852,10 +853,10 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino) #ifdef CONFIG_CIFS_FSCACHE /* populate tcon->resource_id */ - cifs_sb->tcon->resource_id = CIFS_I(inode)->uniqueid; + cifs_sb_tcon(cifs_sb)->resource_id = CIFS_I(inode)->uniqueid; #endif - if (rc && cifs_sb->tcon->ipc) { + if (rc && cifs_sb_tcon(cifs_sb)->ipc) { cFYI(1, "ipc connection - fake read inode"); inode->i_mode |= S_IFDIR; inode->i_nlink = 2; @@ -938,7 +939,7 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid, goto set_via_filehandle; } - pTcon = cifs_sb->tcon; + pTcon = cifs_sb_tcon(cifs_sb); /* * NT4 apparently returns success on this call, but it doesn't @@ -1000,7 +1001,7 @@ cifs_rename_pending_delete(char *full_path, struct dentry *dentry, int xid) struct inode *inode = dentry->d_inode; struct cifsInodeInfo *cifsInode = CIFS_I(inode); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); - struct cifsTconInfo *tcon = cifs_sb->tcon; + struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb); __u32 dosattr, origattr; FILE_BASIC_INFO *info_buf = NULL; @@ -1111,7 +1112,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry) struct cifsInodeInfo *cifs_inode; struct super_block *sb = dir->i_sb; struct cifs_sb_info *cifs_sb = CIFS_SB(sb); - struct cifsTconInfo *tcon = cifs_sb->tcon; + struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb); struct iattr *attrs = NULL; __u32 dosattr = 0, origattr = 0; @@ -1213,7 +1214,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) xid = GetXid(); cifs_sb = CIFS_SB(inode->i_sb); - pTcon = cifs_sb->tcon; + pTcon = cifs_sb_tcon(cifs_sb); full_path = build_path_from_dentry(direntry); if (full_path == NULL) { @@ -1394,7 +1395,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) xid = GetXid(); cifs_sb = CIFS_SB(inode->i_sb); - pTcon = cifs_sb->tcon; + pTcon = cifs_sb_tcon(cifs_sb); full_path = build_path_from_dentry(direntry); if (full_path == NULL) { @@ -1435,7 +1436,7 @@ cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath, struct dentry *to_dentry, const char *toPath) { struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb); - struct cifsTconInfo *pTcon = cifs_sb->tcon; + struct cifsTconInfo *pTcon = cifs_sb_tcon(cifs_sb); __u16 srcfid; int oplock, rc; @@ -1486,7 +1487,7 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry, int xid, rc, tmprc; cifs_sb = CIFS_SB(source_dir->i_sb); - tcon = cifs_sb->tcon; + tcon = cifs_sb_tcon(cifs_sb); xid = GetXid(); @@ -1660,7 +1661,7 @@ int cifs_revalidate_dentry(struct dentry *dentry) "jiffies %ld", full_path, inode, inode->i_count.counter, dentry, dentry->d_time, jiffies); - if (CIFS_SB(sb)->tcon->unix_ext) + if (cifs_sb_tcon(CIFS_SB(sb))->unix_ext) rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid); else rc = cifs_get_inode_info(&inode, full_path, NULL, sb, @@ -1755,7 +1756,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs, if (rc != 0) { if (pTcon == NULL) - pTcon = cifs_sb->tcon; + pTcon = cifs_sb_tcon(cifs_sb); /* Set file size by pathname rather than by handle either because no valid, writeable file handle for @@ -1901,7 +1902,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid); cifsFileInfo_put(open_file); } else { - pTcon = cifs_sb->tcon; + pTcon = cifs_sb_tcon(cifs_sb); rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & @@ -2086,7 +2087,7 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs) { struct inode *inode = direntry->d_inode; struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); - struct cifsTconInfo *pTcon = cifs_sb->tcon; + struct cifsTconInfo *pTcon = cifs_sb_tcon(cifs_sb); if (pTcon->unix_ext) return cifs_setattr_unix(direntry, attrs); diff --git a/fs/cifs/link.c b/fs/cifs/link.c index cbf7b112287b..66db2d61fa43 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c @@ -249,7 +249,7 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr, int rc; int oplock = 0; __u16 netfid = 0; - struct cifsTconInfo *pTcon = cifs_sb->tcon; + struct cifsTconInfo *pTcon = cifs_sb_tcon(cifs_sb); u8 *buf; char *pbuf; unsigned int bytes_read = 0; @@ -321,7 +321,7 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode, xid = GetXid(); cifs_sb_target = CIFS_SB(inode->i_sb); - pTcon = cifs_sb_target->tcon; + pTcon = cifs_sb_tcon(cifs_sb_target); /* 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) */ @@ -390,7 +390,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd) char *full_path = NULL; char *target_path = NULL; struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); - struct cifsTconInfo *tcon = cifs_sb->tcon; + struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb); xid = GetXid(); @@ -459,7 +459,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname) xid = GetXid(); cifs_sb = CIFS_SB(inode->i_sb); - pTcon = cifs_sb->tcon; + pTcon = cifs_sb_tcon(cifs_sb); full_path = build_path_from_dentry(direntry); diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 3ccadc1326d6..c5cbfdb2a58b 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -729,6 +729,6 @@ cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb) "properly. Hardlinks will not be recognized on this " "mount. Consider mounting with the \"noserverino\" " "option to silence this message.", - cifs_sb->tcon->treeName); + cifs_sb_tcon(cifs_sb)->treeName); } } diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index d7784a95134f..3efc2424964f 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -102,7 +102,7 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name, return NULL; } - if (CIFS_SB(sb)->tcon->nocase) + if (cifs_sb_tcon(CIFS_SB(sb))->nocase) dentry->d_op = &cifs_ci_dentry_ops; else dentry->d_op = &cifs_dentry_ops; @@ -171,7 +171,7 @@ static void cifs_std_info_to_fattr(struct cifs_fattr *fattr, FIND_FILE_STANDARD_INFO *info, struct cifs_sb_info *cifs_sb) { - int offset = cifs_sb->tcon->ses->server->timeAdj; + int offset = cifs_sb_tcon(cifs_sb)->ses->server->timeAdj; memset(fattr, 0, sizeof(*fattr)); fattr->cf_atime = cnvrtDosUnixTm(info->LastAccessDate, @@ -199,7 +199,7 @@ int get_symlink_reparse_path(char *full_path, struct cifs_sb_info *cifs_sb, int len; int oplock = 0; int rc; - struct cifsTconInfo *ptcon = cifs_sb->tcon; + struct cifsTconInfo *ptcon = cifs_sb_tcon(cifs_sb); char *tmpbuffer; rc = CIFSSMBOpen(xid, ptcon, full_path, FILE_OPEN, GENERIC_READ, @@ -241,7 +241,7 @@ static int initiate_cifs_search(const int xid, struct file *file) cifsFile = file->private_data; cifsFile->invalidHandle = true; cifsFile->srch_inf.endOfSearch = false; - cifsFile->tcon = cifs_sb->tcon; + cifsFile->tcon = cifs_sb_tcon(cifs_sb); pTcon = cifsFile->tcon; if (pTcon == NULL) return -EINVAL; diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index a1509207bfa6..41f95bf67977 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c @@ -61,7 +61,7 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name) xid = GetXid(); cifs_sb = CIFS_SB(sb); - pTcon = cifs_sb->tcon; + pTcon = cifs_sb_tcon(cifs_sb); full_path = build_path_from_dentry(direntry); if (full_path == NULL) { @@ -116,7 +116,7 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, xid = GetXid(); cifs_sb = CIFS_SB(sb); - pTcon = cifs_sb->tcon; + pTcon = cifs_sb_tcon(cifs_sb); full_path = build_path_from_dentry(direntry); if (full_path == NULL) { @@ -224,7 +224,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name, xid = GetXid(); cifs_sb = CIFS_SB(sb); - pTcon = cifs_sb->tcon; + pTcon = cifs_sb_tcon(cifs_sb); full_path = build_path_from_dentry(direntry); if (full_path == NULL) { @@ -346,7 +346,7 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size) return -EIO; cifs_sb = CIFS_SB(sb); - pTcon = cifs_sb->tcon; + pTcon = cifs_sb_tcon(cifs_sb); if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) return -EOPNOTSUPP; -- cgit v1.2.3-59-g8ed1b From 0d424ad0a4b8c08e45928bccfa5b4b240097b01b Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 20 Sep 2010 16:01:35 -0700 Subject: cifs: add cifs_sb_master_tcon and convert some callers to use it At mount time, we'll always need to create a tcon that will serve as a template for others that are associated with the mount. This tcon is known as the "master" tcon. In some cases, we'll need to use that tcon regardless of who's accessing the mount. Add an accessor function for the master tcon and go ahead and switch the appropriate places to use it. Signed-off-by: Jeff Layton Signed-off-by: Steve French --- fs/cifs/cifsfs.c | 6 +++--- fs/cifs/cifsglob.h | 7 +++++++ fs/cifs/connect.c | 4 ++-- fs/cifs/dir.c | 10 +++++----- fs/cifs/fscache.c | 12 ++++++------ fs/cifs/inode.c | 29 ++++++++++++++++------------- fs/cifs/misc.c | 2 +- fs/cifs/readdir.c | 4 ++-- 8 files changed, 42 insertions(+), 32 deletions(-) (limited to 'fs/cifs/cifsfs.c') diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index b9624abb7261..898d2a5cfad2 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -222,7 +222,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf) { struct super_block *sb = dentry->d_sb; struct cifs_sb_info *cifs_sb = CIFS_SB(sb); - struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb); + struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); int rc = -EOPNOTSUPP; int xid; @@ -364,7 +364,7 @@ static int cifs_show_options(struct seq_file *s, struct vfsmount *m) { struct cifs_sb_info *cifs_sb = CIFS_SB(m->mnt_sb); - struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb); + struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); struct sockaddr *srcaddr; srcaddr = (struct sockaddr *)&tcon->ses->server->srcaddr; @@ -455,7 +455,7 @@ static void cifs_umount_begin(struct super_block *sb) if (cifs_sb == NULL) return; - tcon = cifs_sb_tcon(cifs_sb); + tcon = cifs_sb_master_tcon(cifs_sb); read_lock(&cifs_tcp_ses_lock); if ((tcon->tc_count > 1) || (tcon->tidStatus == CifsExiting)) { diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index cc8300c741b6..c265ebdcd177 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -419,6 +419,13 @@ cifs_sb_tcon(struct cifs_sb_info *cifs_sb) return cifs_sb->ptcon; } +/* This function is always expected to succeed */ +static inline struct cifsTconInfo * +cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb) +{ + return cifs_sb->ptcon; +} + static inline char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb) { if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index b4bacea54626..f6a3091c2874 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -3025,9 +3025,9 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) { int rc = 0; char *tmp; + struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); - if (cifs_sb_tcon(cifs_sb)) - cifs_put_tcon(cifs_sb_tcon(cifs_sb)); + cifs_put_tcon(tcon); cifs_sb->ptcon = NULL; tmp = cifs_sb->prepath; diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index f660a15eb14f..fe02435acb3c 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -54,18 +54,18 @@ build_path_from_dentry(struct dentry *direntry) int dfsplen; char *full_path; char dirsep; - struct cifs_sb_info *cifs_sb; + struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb); + struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); if (direntry == NULL) return NULL; /* not much we can do if dentry is freed and we need to reopen the file after it was closed implicitly when the server crashed */ - cifs_sb = CIFS_SB(direntry->d_sb); dirsep = CIFS_DIR_SEP(cifs_sb); pplen = cifs_sb->prepathlen; - if (cifs_sb_tcon(cifs_sb) && (cifs_sb_tcon(cifs_sb)->Flags & SMB_SHARE_IS_IN_DFS)) - dfsplen = strnlen(cifs_sb_tcon(cifs_sb)->treeName, MAX_TREE_SIZE + 1); + if (tcon->Flags & SMB_SHARE_IS_IN_DFS) + dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1); else dfsplen = 0; cifs_bp_rename_retry: @@ -117,7 +117,7 @@ cifs_bp_rename_retry: /* BB test paths to Windows with '/' in the midst of prepath */ if (dfsplen) { - strncpy(full_path, cifs_sb_tcon(cifs_sb)->treeName, dfsplen); + strncpy(full_path, tcon->treeName, dfsplen); if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) { int i; for (i = 0; i < dfsplen; i++) { diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c index ec4318b019cc..a2ad94efcfe6 100644 --- a/fs/cifs/fscache.c +++ b/fs/cifs/fscache.c @@ -62,15 +62,15 @@ static void cifs_fscache_enable_inode_cookie(struct inode *inode) { struct cifsInodeInfo *cifsi = CIFS_I(inode); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); if (cifsi->fscache) return; - cifsi->fscache = fscache_acquire_cookie(cifs_sb_tcon(cifs_sb)->fscache, - &cifs_fscache_inode_object_def, - cifsi); - cFYI(1, "CIFS: got FH cookie (0x%p/0x%p)", - cifs_sb_tcon(cifs_sb)->fscache, cifsi->fscache); + cifsi->fscache = fscache_acquire_cookie(tcon->fscache, + &cifs_fscache_inode_object_def, cifsi); + cFYI(1, "CIFS: got FH cookie (0x%p/0x%p)", tcon->fscache, + cifsi->fscache); } void cifs_fscache_release_inode_cookie(struct inode *inode) @@ -118,7 +118,7 @@ void cifs_fscache_reset_inode_cookie(struct inode *inode) fscache_relinquish_cookie(cifsi->fscache, 1); cifsi->fscache = fscache_acquire_cookie( - cifs_sb_tcon(cifs_sb)->fscache, + cifs_sb_master_tcon(cifs_sb)->fscache, &cifs_fscache_inode_object_def, cifsi); cFYI(1, "CIFS: new cookie 0x%p oldcookie 0x%p", diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index dce2d598927e..da716d96dae6 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -52,7 +52,7 @@ static void cifs_set_ops(struct inode *inode, const bool is_dfs_referral) /* check if server can support readpages */ - if (cifs_sb_tcon(cifs_sb)->ses->server->maxBuf < + if (cifs_sb_master_tcon(cifs_sb)->ses->server->maxBuf < PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE) inode->i_data.a_ops = &cifs_addr_ops_smallbuf; else @@ -476,6 +476,8 @@ static void cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, struct cifs_sb_info *cifs_sb, bool adjust_tz) { + struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); + memset(fattr, 0, sizeof(*fattr)); fattr->cf_cifsattrs = le32_to_cpu(info->Attributes); if (info->DeletePending) @@ -490,8 +492,8 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime); if (adjust_tz) { - fattr->cf_ctime.tv_sec += cifs_sb_tcon(cifs_sb)->ses->server->timeAdj; - fattr->cf_mtime.tv_sec += cifs_sb_tcon(cifs_sb)->ses->server->timeAdj; + fattr->cf_ctime.tv_sec += tcon->ses->server->timeAdj; + fattr->cf_mtime.tv_sec += tcon->ses->server->timeAdj; } fattr->cf_eof = le64_to_cpu(info->EndOfFile); @@ -698,6 +700,7 @@ char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb) int pplen = cifs_sb->prepathlen; int dfsplen; char *full_path = NULL; + struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); /* if no prefix path, simply set path to the root of share to "" */ if (pplen == 0) { @@ -707,8 +710,8 @@ char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb) return full_path; } - if (cifs_sb_tcon(cifs_sb) && (cifs_sb_tcon(cifs_sb)->Flags & SMB_SHARE_IS_IN_DFS)) - dfsplen = strnlen(cifs_sb_tcon(cifs_sb)->treeName, MAX_TREE_SIZE + 1); + if (tcon->Flags & SMB_SHARE_IS_IN_DFS) + dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1); else dfsplen = 0; @@ -717,7 +720,7 @@ char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb) return full_path; if (dfsplen) { - strncpy(full_path, cifs_sb_tcon(cifs_sb)->treeName, dfsplen); + strncpy(full_path, tcon->treeName, dfsplen); /* switch slash direction in prepath depending on whether * windows or posix style path names */ @@ -831,18 +834,18 @@ retry_iget5_locked: struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino) { int xid; - struct cifs_sb_info *cifs_sb; + struct cifs_sb_info *cifs_sb = CIFS_SB(sb); struct inode *inode = NULL; long rc; char *full_path; + struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); - cifs_sb = CIFS_SB(sb); full_path = cifs_build_path_to_root(cifs_sb); if (full_path == NULL) return ERR_PTR(-ENOMEM); xid = GetXid(); - if (cifs_sb_tcon(cifs_sb)->unix_ext) + if (tcon->unix_ext) rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid); else rc = cifs_get_inode_info(&inode, full_path, NULL, sb, @@ -853,10 +856,10 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino) #ifdef CONFIG_CIFS_FSCACHE /* populate tcon->resource_id */ - cifs_sb_tcon(cifs_sb)->resource_id = CIFS_I(inode)->uniqueid; + tcon->resource_id = CIFS_I(inode)->uniqueid; #endif - if (rc && cifs_sb_tcon(cifs_sb)->ipc) { + if (rc && tcon->ipc) { cFYI(1, "ipc connection - fake read inode"); inode->i_mode |= S_IFDIR; inode->i_nlink = 2; @@ -1661,7 +1664,7 @@ int cifs_revalidate_dentry(struct dentry *dentry) "jiffies %ld", full_path, inode, inode->i_count.counter, dentry, dentry->d_time, jiffies); - if (cifs_sb_tcon(CIFS_SB(sb))->unix_ext) + if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext) rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid); else rc = cifs_get_inode_info(&inode, full_path, NULL, sb, @@ -2087,7 +2090,7 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs) { struct inode *inode = direntry->d_inode; struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); - struct cifsTconInfo *pTcon = cifs_sb_tcon(cifs_sb); + struct cifsTconInfo *pTcon = cifs_sb_master_tcon(cifs_sb); if (pTcon->unix_ext) return cifs_setattr_unix(direntry, attrs); diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index c5cbfdb2a58b..252f2768db84 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -729,6 +729,6 @@ cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb) "properly. Hardlinks will not be recognized on this " "mount. Consider mounting with the \"noserverino\" " "option to silence this message.", - cifs_sb_tcon(cifs_sb)->treeName); + cifs_sb_master_tcon(cifs_sb)->treeName); } } diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 3efc2424964f..887a7e230376 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -102,7 +102,7 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name, return NULL; } - if (cifs_sb_tcon(CIFS_SB(sb))->nocase) + if (cifs_sb_master_tcon(CIFS_SB(sb))->nocase) dentry->d_op = &cifs_ci_dentry_ops; else dentry->d_op = &cifs_dentry_ops; @@ -171,7 +171,7 @@ static void cifs_std_info_to_fattr(struct cifs_fattr *fattr, FIND_FILE_STANDARD_INFO *info, struct cifs_sb_info *cifs_sb) { - int offset = cifs_sb_tcon(cifs_sb)->ses->server->timeAdj; + int offset = cifs_sb_master_tcon(cifs_sb)->ses->server->timeAdj; memset(fattr, 0, sizeof(*fattr)); fattr->cf_atime = cnvrtDosUnixTm(info->LastAccessDate, -- cgit v1.2.3-59-g8ed1b From 13cfb7334eb6fd0fc06da5589aea1e947791f1d6 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Wed, 29 Sep 2010 19:51:11 -0400 Subject: cifs: have cifsFileInfo hold a reference to a tlink rather than tcon pointer cifsFileInfo needs a pointer to a tcon, but it doesn't currently hold a reference to it. Change it to keep a pointer to a tcon_link instead and hold a reference to it. That will keep the tcon from being freed until the file is closed. Signed-off-by: Jeff Layton Signed-off-by: Steve French --- fs/cifs/cifsfs.c | 3 ++- fs/cifs/cifsglob.h | 9 ++++++++- fs/cifs/cifsproto.h | 2 +- fs/cifs/dir.c | 10 +++++----- fs/cifs/file.c | 31 ++++++++++++++++--------------- fs/cifs/inode.c | 12 ++++++------ fs/cifs/ioctl.c | 2 +- fs/cifs/link.c | 1 - fs/cifs/readdir.c | 4 ++-- 9 files changed, 41 insertions(+), 33 deletions(-) (limited to 'fs/cifs/cifsfs.c') diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 898d2a5cfad2..b2fd075dc2e6 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -595,7 +595,8 @@ static int cifs_setlease(struct file *file, long arg, struct file_lock **lease) ((arg == F_WRLCK) && (CIFS_I(inode)->clientCanCacheAll))) return generic_setlease(file, arg, lease); - else if (cfile->tcon->local_lease && !CIFS_I(inode)->clientCanCacheRead) + else if (tlink_tcon(cfile->tlink)->local_lease && + !CIFS_I(inode)->clientCanCacheRead) /* If the server claims to support oplock on this file, then we still need to check oplock even if the local_lease mount option is set, but there diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index cdfd2db4e70d..d5324853203b 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -341,6 +341,12 @@ cifs_put_tlink(struct tcon_link *tlink) return; } +static inline struct tcon_link * +cifs_get_tlink(struct tcon_link *tlink) +{ + return tlink; +} + /* This function is always expected to succeed */ static inline struct cifsTconInfo * cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb) @@ -389,7 +395,7 @@ struct cifsFileInfo { struct file *pfile; /* needed for writepage */ struct inode *pInode; /* needed for oplock break */ struct vfsmount *mnt; - struct cifsTconInfo *tcon; + struct tcon_link *tlink; struct mutex lock_mutex; struct list_head llist; /* list of byte range locks we have. */ bool closePend:1; /* file is marked to close */ @@ -411,6 +417,7 @@ static inline void cifsFileInfo_get(struct cifsFileInfo *cifs_file) static inline void cifsFileInfo_put(struct cifsFileInfo *cifs_file) { if (atomic_dec_and_test(&cifs_file->count)) { + cifs_put_tlink(cifs_file->tlink); iput(cifs_file->pInode); kfree(cifs_file); } diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 610b2263c9f3..7294723d0625 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -107,7 +107,7 @@ extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, extern struct cifsFileInfo *cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, struct file *file, - struct vfsmount *mnt, struct cifsTconInfo *tcon, + struct vfsmount *mnt, struct tcon_link *tlink, unsigned int oflags, __u32 oplock); extern int cifs_posix_open(char *full_path, struct inode **pinode, struct super_block *sb, diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index bb3ea06ca6f4..5adf47f28fed 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -132,7 +132,7 @@ cifs_bp_rename_retry: struct cifsFileInfo * cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, struct file *file, - struct vfsmount *mnt, struct cifsTconInfo *tcon, + struct vfsmount *mnt, struct tcon_link *tlink, unsigned int oflags, __u32 oplock) { struct cifsFileInfo *pCifsFile; @@ -149,7 +149,7 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, struct file *file, pCifsFile->pfile = file; pCifsFile->invalidHandle = false; pCifsFile->closePend = false; - pCifsFile->tcon = tcon; + pCifsFile->tlink = cifs_get_tlink(tlink); mutex_init(&pCifsFile->fh_mutex); mutex_init(&pCifsFile->lock_mutex); INIT_LIST_HEAD(&pCifsFile->llist); @@ -157,7 +157,7 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, struct file *file, INIT_WORK(&pCifsFile->oplock_break, cifs_oplock_break); write_lock(&GlobalSMBSeslock); - list_add(&pCifsFile->tlist, &tcon->openFileList); + list_add(&pCifsFile->tlist, &(tlink_tcon(tlink)->openFileList)); pCifsInode = CIFS_I(newinode); if (pCifsInode) { /* if readable file instance put first in list*/ @@ -483,7 +483,7 @@ cifs_create_set_dentry: } pfile_info = cifs_new_fileinfo(newinode, fileHandle, filp, - nd->path.mnt, tcon, oflags, + nd->path.mnt, tlink, oflags, oplock); if (pfile_info == NULL) { fput(filp); @@ -758,7 +758,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, } cfile = cifs_new_fileinfo(newInode, fileHandle, filp, - nd->path.mnt, pTcon, + nd->path.mnt, tlink, nd->intent.open.flags, oplock); if (cfile == NULL) { diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 1e375abc5eb3..24332d437150 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -283,7 +283,7 @@ int cifs_open(struct inode *inode, struct file *file) pCifsFile = cifs_new_fileinfo(inode, netfid, file, file->f_path.mnt, - tcon, oflags, oplock); + tlink, oflags, oplock); if (pCifsFile == NULL) { CIFSSMBClose(xid, tcon, netfid); rc = -ENOMEM; @@ -376,7 +376,7 @@ int cifs_open(struct inode *inode, struct file *file) goto out; pCifsFile = cifs_new_fileinfo(inode, netfid, file, file->f_path.mnt, - tcon, file->f_flags, oplock); + tlink, file->f_flags, oplock); if (pCifsFile == NULL) { rc = -ENOMEM; goto out; @@ -468,7 +468,7 @@ static int cifs_reopen_file(struct file *file, bool can_flush) } cifs_sb = CIFS_SB(inode->i_sb); - tcon = pCifsFile->tcon; + tcon = tlink_tcon(pCifsFile->tlink); /* can not grab rename sem here because various ops, including those that already have the rename sem can end up causing writepage @@ -582,7 +582,7 @@ int cifs_close(struct inode *inode, struct file *file) xid = GetXid(); cifs_sb = CIFS_SB(inode->i_sb); - pTcon = pSMBFile->tcon; + pTcon = tlink_tcon(pSMBFile->tlink); if (pSMBFile) { struct cifsLockInfo *li, *tmp; write_lock(&GlobalSMBSeslock); @@ -660,7 +660,7 @@ int cifs_closedir(struct inode *inode, struct file *file) xid = GetXid(); if (pCFileStruct) { - struct cifsTconInfo *pTcon = pCFileStruct->tcon; + struct cifsTconInfo *pTcon = tlink_tcon(pCFileStruct->tlink); cFYI(1, "Freeing private data in close dir"); write_lock(&GlobalSMBSeslock); @@ -684,6 +684,7 @@ int cifs_closedir(struct inode *inode, struct file *file) else cifs_buf_release(ptmp); } + cifs_put_tlink(pCFileStruct->tlink); kfree(file->private_data); file->private_data = NULL; } @@ -770,7 +771,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) cFYI(1, "Unknown type of lock"); cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); - tcon = ((struct cifsFileInfo *)file->private_data)->tcon; + tcon = tlink_tcon(((struct cifsFileInfo *)file->private_data)->tlink); if (file->private_data == NULL) { rc = -EBADF; @@ -970,7 +971,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, return -EBADF; open_file = file->private_data; - pTcon = open_file->tcon; + pTcon = tlink_tcon(open_file->tlink); rc = generic_write_checks(file, poffset, &write_size, 0); if (rc) @@ -1071,7 +1072,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data, if (file->private_data == NULL) return -EBADF; open_file = file->private_data; - pTcon = open_file->tcon; + pTcon = tlink_tcon(open_file->tlink); xid = GetXid(); @@ -1393,7 +1394,7 @@ static int cifs_writepages(struct address_space *mapping, return generic_writepages(mapping, wbc); } - tcon = open_file->tcon; + tcon = tlink_tcon(open_file->tlink); if (!experimEnabled && tcon->ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { cifsFileInfo_put(open_file); @@ -1672,7 +1673,7 @@ int cifs_fsync(struct file *file, int datasync) if (rc == 0) { rc = CIFS_I(inode)->write_behind_rc; CIFS_I(inode)->write_behind_rc = 0; - tcon = smbfile->tcon; + tcon = tlink_tcon(smbfile->tlink); if (!rc && tcon && smbfile && !(CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) rc = CIFSSMBFlush(xid, tcon, smbfile->netfid); @@ -1764,7 +1765,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, return rc; } open_file = file->private_data; - pTcon = open_file->tcon; + pTcon = tlink_tcon(open_file->tlink); if ((file->f_flags & O_ACCMODE) == O_WRONLY) cFYI(1, "attempting read on write only file instance"); @@ -1845,7 +1846,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, return rc; } open_file = file->private_data; - pTcon = open_file->tcon; + pTcon = tlink_tcon(open_file->tlink); if ((file->f_flags & O_ACCMODE) == O_WRONLY) cFYI(1, "attempting read on write only file instance"); @@ -1981,7 +1982,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, } open_file = file->private_data; cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); - pTcon = open_file->tcon; + pTcon = tlink_tcon(open_file->tlink); /* * Reads as many pages as possible from fscache. Returns -ENOBUFS @@ -2345,8 +2346,8 @@ void cifs_oplock_break(struct work_struct *work) * disconnected since oplock already released by the server */ if (!cfile->closePend && !cfile->oplock_break_cancelled) { - rc = CIFSSMBLock(0, cfile->tcon, cfile->netfid, 0, 0, 0, 0, - LOCKING_ANDX_OPLOCK_RELEASE, false); + rc = CIFSSMBLock(0, tlink_tcon(cfile->tlink), cfile->netfid, 0, + 0, 0, 0, LOCKING_ANDX_OPLOCK_RELEASE, false); cFYI(1, "Oplock release rc = %d", rc); } diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index aa229692aef1..a39a1c451733 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -289,7 +289,7 @@ int cifs_get_file_info_unix(struct file *filp) struct inode *inode = filp->f_path.dentry->d_inode; struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifsFileInfo *cfile = filp->private_data; - struct cifsTconInfo *tcon = cfile->tcon; + struct cifsTconInfo *tcon = tlink_tcon(cfile->tlink); xid = GetXid(); rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data); @@ -546,7 +546,7 @@ int cifs_get_file_info(struct file *filp) struct inode *inode = filp->f_path.dentry->d_inode; struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifsFileInfo *cfile = filp->private_data; - struct cifsTconInfo *tcon = cfile->tcon; + struct cifsTconInfo *tcon = tlink_tcon(cfile->tlink); xid = GetXid(); rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data); @@ -967,7 +967,7 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid, if (open_file) { netfid = open_file->netfid; netpid = open_file->pid; - pTcon = open_file->tcon; + pTcon = tlink_tcon(open_file->tlink); goto set_via_filehandle; } @@ -1696,7 +1696,7 @@ int cifs_revalidate_file(struct file *filp) if (!cifs_inode_needs_reval(inode)) goto check_inval; - if (cfile->tcon->unix_ext) + if (tlink_tcon(cfile->tlink)->unix_ext) rc = cifs_get_file_info_unix(filp); else rc = cifs_get_file_info(filp); @@ -1817,7 +1817,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs, if (open_file) { __u16 nfid = open_file->netfid; __u32 npid = open_file->pid; - pTcon = open_file->tcon; + pTcon = tlink_tcon(open_file->tlink); rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid, npid, false); cifsFileInfo_put(open_file); @@ -1982,7 +1982,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) if (open_file) { u16 nfid = open_file->netfid; u32 npid = open_file->pid; - pTcon = open_file->tcon; + pTcon = tlink_tcon(open_file->tlink); rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid); cifsFileInfo_put(open_file); } else { diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c index cc70a61a47d2..077bf756f342 100644 --- a/fs/cifs/ioctl.c +++ b/fs/cifs/ioctl.c @@ -38,7 +38,7 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) struct cifs_sb_info *cifs_sb; #ifdef CONFIG_CIFS_POSIX struct cifsFileInfo *pSMBFile = filep->private_data; - struct cifsTconInfo *tcon = pSMBFile->tcon; + struct cifsTconInfo *tcon = tlink_tcon(pSMBFile->tlink); __u64 ExtAttrBits = 0; __u64 ExtAttrMask = 0; __u64 caps = le64_to_cpu(tcon->fsUnixInfo.Capability); diff --git a/fs/cifs/link.c b/fs/cifs/link.c index b38fe6704ad2..85cdbf831e7b 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c @@ -346,7 +346,6 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode, goto cifs_hl_exit; } -/* if (cifs_sb_target->tcon->ses->capabilities & CAP_UNIX)*/ if (pTcon->unix_ext) rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName, cifs_sb->local_nls, diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 170047cf4522..1f0bd0f972d4 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -245,7 +245,7 @@ static int initiate_cifs_search(const int xid, struct file *file) cifsFile = file->private_data; cifsFile->invalidHandle = true; cifsFile->srch_inf.endOfSearch = false; - cifsFile->tcon = pTcon; + cifsFile->tlink = cifs_get_tlink(tlink); full_path = build_path_from_dentry(file->f_path.dentry); if (full_path == NULL) { @@ -838,7 +838,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) CIFSFindClose(xid, pTcon, cifsFile->netfid); } */ - pTcon = cifsFile->tcon; + pTcon = tlink_tcon(cifsFile->tlink); rc = find_cifs_entry(xid, pTcon, file, ¤t_entry, &num_to_fill); if (rc) { -- cgit v1.2.3-59-g8ed1b From 29e07c82a9e8acebbb38ecc22b0b5005a0a5d839 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Wed, 29 Sep 2010 19:51:12 -0400 Subject: cifs: fix cifs_show_options to show "username=" or "multiuser" ...based on CIFS_MOUNT_MULTIUSER flag. Signed-off-by: Jeff Layton Signed-off-by: Steve French --- fs/cifs/cifsfs.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'fs/cifs/cifsfs.c') diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index b2fd075dc2e6..c96345c3314d 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -369,8 +369,12 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m) srcaddr = (struct sockaddr *)&tcon->ses->server->srcaddr; seq_printf(s, ",unc=%s", tcon->treeName); - if (tcon->ses->userName) + + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) + seq_printf(s, ",multiuser"); + else if (tcon->ses->userName) seq_printf(s, ",username=%s", tcon->ses->userName); + if (tcon->ses->domainName) seq_printf(s, ",domain=%s", tcon->ses->domainName); -- cgit v1.2.3-59-g8ed1b From 0dd12c21951e085357046b68c3a108273062d2aa Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Fri, 8 Oct 2010 12:20:12 -0400 Subject: cifs: initialize tlink_tree_lock and tlink_tree Signed-off-by: Jeff Layton Signed-off-by: Steve French --- fs/cifs/cifsfs.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'fs/cifs/cifsfs.c') diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index c96345c3314d..3258c822328b 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -98,6 +98,9 @@ cifs_read_super(struct super_block *sb, void *data, if (cifs_sb == NULL) return -ENOMEM; + spin_lock_init(&cifs_sb->tlink_tree_lock); + INIT_RADIX_TREE(&cifs_sb->tlink_tree, GFP_KERNEL); + rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); if (rc) { kfree(cifs_sb); -- cgit v1.2.3-59-g8ed1b From d7c86ff8cd00abc730fe5d031f43dc9138b6324e Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 11 Oct 2010 15:07:19 -0400 Subject: cifs: don't use vfsmount to pin superblock for oplock breaks Filesystems aren't really supposed to do anything with a vfsmount. It's considered a layering violation since vfsmounts are entirely managed at the VFS layer. CIFS currently keeps an active reference to a vfsmount in order to prevent the superblock vanishing before an oplock break has completed. What we really want to do instead is to keep sb->s_active high until the oplock break has completed. This patch borrows the scheme that NFS uses for handling sillyrenames. An atomic_t is added to the cifs_sb_info. When it transitions from 0 to 1, an extra reference to the superblock is taken (by bumping the s_active value). When it transitions from 1 to 0, that reference is dropped and a the superblock teardown may proceed if there are no more references to it. Also, the vfsmount pointer is removed from cifsFileInfo and from cifs_new_fileinfo, and some bogus forward declarations are removed from cifsfs.h. Signed-off-by: Jeff Layton Reviewed-by: Suresh Jayaraman Acked-by: Dave Kleikamp Signed-off-by: Steve French --- fs/cifs/cifs_fs_sb.h | 1 + fs/cifs/cifsfs.c | 18 ++++++++++++++++++ fs/cifs/cifsfs.h | 6 ++---- fs/cifs/cifsglob.h | 1 - fs/cifs/cifsproto.h | 2 +- fs/cifs/dir.c | 10 +++------- fs/cifs/file.c | 9 ++++----- 7 files changed, 29 insertions(+), 18 deletions(-) (limited to 'fs/cifs/cifsfs.c') diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index 586ee3d527d2..525ba59a4105 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h @@ -48,6 +48,7 @@ struct cifs_sb_info { struct nls_table *local_nls; unsigned int rsize; unsigned int wsize; + atomic_t active; uid_t mnt_uid; gid_t mnt_gid; mode_t mnt_file_mode; diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 3258c822328b..cbd468c880c4 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -83,6 +83,24 @@ extern mempool_t *cifs_sm_req_poolp; extern mempool_t *cifs_req_poolp; extern mempool_t *cifs_mid_poolp; +void +cifs_sb_active(struct super_block *sb) +{ + struct cifs_sb_info *server = CIFS_SB(sb); + + if (atomic_inc_return(&server->active) == 1) + atomic_inc(&sb->s_active); +} + +void +cifs_sb_deactive(struct super_block *sb) +{ + struct cifs_sb_info *server = CIFS_SB(sb); + + if (atomic_dec_and_test(&server->active)) + deactivate_super(sb); +} + static int cifs_read_super(struct super_block *sb, void *data, const char *devname, int silent) diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 786bdf36aebf..85544bcab517 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h @@ -42,10 +42,8 @@ extern const struct address_space_operations cifs_addr_ops; extern const struct address_space_operations cifs_addr_ops_smallbuf; /* Functions related to super block operations */ -/* extern const struct super_operations cifs_super_ops;*/ -extern void cifs_read_inode(struct inode *); -/*extern void cifs_delete_inode(struct inode *);*/ /* BB not needed yet */ -/* extern void cifs_write_inode(struct inode *); */ /* BB not needed yet */ +extern void cifs_sb_active(struct super_block *sb); +extern void cifs_sb_deactive(struct super_block *sb); /* Functions related to inodes */ extern const struct inode_operations cifs_dir_inode_ops; diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 8289e61937a2..e2b760ef22ff 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -388,7 +388,6 @@ struct cifsFileInfo { /* lock scope id (0 if none) */ struct file *pfile; /* needed for writepage */ struct dentry *dentry; - struct vfsmount *mnt; struct tcon_link *tlink; struct mutex lock_mutex; struct list_head llist; /* list of byte range locks we have. */ diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 29a2ee8ae51f..7f416abd34cf 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -107,7 +107,7 @@ extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, extern struct cifsFileInfo *cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, struct file *file, - struct vfsmount *mnt, struct tcon_link *tlink, + struct tcon_link *tlink, unsigned int oflags, __u32 oplock); extern int cifs_posix_open(char *full_path, struct inode **pinode, struct super_block *sb, diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 6887c412c61a..c205ec9293ea 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -132,8 +132,7 @@ cifs_bp_rename_retry: struct cifsFileInfo * cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, struct file *file, - struct vfsmount *mnt, struct tcon_link *tlink, - unsigned int oflags, __u32 oplock) + struct tcon_link *tlink, unsigned int oflags, __u32 oplock) { struct dentry *dentry = file->f_path.dentry; struct cifsFileInfo *pCifsFile; @@ -147,7 +146,6 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, struct file *file, pCifsFile->pid = current->tgid; pCifsFile->uid = current_fsuid(); pCifsFile->dentry = dget(dentry); - pCifsFile->mnt = mnt; pCifsFile->pfile = file; pCifsFile->invalidHandle = false; pCifsFile->closePend = false; @@ -485,8 +483,7 @@ cifs_create_set_dentry: } pfile_info = cifs_new_fileinfo(newinode, fileHandle, filp, - nd->path.mnt, tlink, oflags, - oplock); + tlink, oflags, oplock); if (pfile_info == NULL) { fput(filp); CIFSSMBClose(xid, tcon, fileHandle); @@ -760,8 +757,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, } cfile = cifs_new_fileinfo(newInode, fileHandle, filp, - nd->path.mnt, tlink, - nd->intent.open.flags, + tlink, nd->intent.open.flags, oplock); if (cfile == NULL) { fput(filp); diff --git a/fs/cifs/file.c b/fs/cifs/file.c index c302b9c52644..fd78a355f634 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -282,7 +282,6 @@ int cifs_open(struct inode *inode, struct file *file) } pCifsFile = cifs_new_fileinfo(inode, netfid, file, - file->f_path.mnt, tlink, oflags, oplock); if (pCifsFile == NULL) { CIFSSMBClose(xid, tcon, netfid); @@ -375,8 +374,8 @@ int cifs_open(struct inode *inode, struct file *file) if (rc != 0) goto out; - pCifsFile = cifs_new_fileinfo(inode, netfid, file, file->f_path.mnt, - tlink, file->f_flags, oplock); + pCifsFile = cifs_new_fileinfo(inode, netfid, file, tlink, + file->f_flags, oplock); if (pCifsFile == NULL) { rc = -ENOMEM; goto out; @@ -2381,14 +2380,14 @@ void cifs_oplock_break(struct work_struct *work) void cifs_oplock_break_get(struct cifsFileInfo *cfile) { - mntget(cfile->mnt); + cifs_sb_active(cfile->dentry->d_sb); cifsFileInfo_get(cfile); } void cifs_oplock_break_put(struct cifsFileInfo *cfile) { - mntput(cfile->mnt); cifsFileInfo_put(cfile); + cifs_sb_deactive(cfile->dentry->d_sb); } const struct address_space_operations cifs_addr_ops = { -- cgit v1.2.3-59-g8ed1b From 4477288a103631980750c86547d1fd54bfd2ba7d Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Fri, 15 Oct 2010 15:34:03 -0400 Subject: cifs: convert GlobalSMBSeslock from a rwlock to regular spinlock Convert this lock to a regular spinlock A rwlock_t offers little value here. It's more expensive than a regular spinlock unless you have a fairly large section of code that runs under the read lock and can benefit from the concurrency. Additionally, we need to ensure that the refcounting for files isn't racy and to do that we need to lock areas that can increment it for write. That means that the areas that can actually use a read_lock are very few and relatively infrequently used. While we're at it, change the name to something easier to type, and fix a bug in find_writable_file. cifsFileInfo_put can sleep and shouldn't be called while holding the lock. Signed-off-by: Jeff Layton Reviewed-by: Suresh Jayaraman Signed-off-by: Steve French --- fs/cifs/cifsfs.c | 2 +- fs/cifs/cifsglob.h | 2 +- fs/cifs/cifssmb.c | 4 ++-- fs/cifs/file.c | 54 +++++++++++++++++++++++++++--------------------------- fs/cifs/misc.c | 8 ++++---- fs/cifs/readdir.c | 6 +++--- 6 files changed, 38 insertions(+), 38 deletions(-) (limited to 'fs/cifs/cifsfs.c') diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index cbd468c880c4..f1d9c71e807f 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -940,8 +940,8 @@ init_cifs(void) GlobalTotalActiveXid = 0; GlobalMaxActiveXid = 0; memset(Local_System_Name, 0, 15); - rwlock_init(&GlobalSMBSeslock); rwlock_init(&cifs_tcp_ses_lock); + spin_lock_init(&cifs_file_list_lock); spin_lock_init(&GlobalMid_Lock); if (cifs_max_pending < 2) { diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 9f99afab9a04..53899a8d7c4a 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -720,7 +720,7 @@ GLOBAL_EXTERN rwlock_t cifs_tcp_ses_lock; * If cifs_tcp_ses_lock and the lock below are both needed to be held, then * the cifs_tcp_ses_lock must be grabbed first and released last. */ -GLOBAL_EXTERN rwlock_t GlobalSMBSeslock; +GLOBAL_EXTERN spinlock_t cifs_file_list_lock; /* Outstanding dir notify requests */ GLOBAL_EXTERN struct list_head GlobalDnotifyReqList; diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index a420c7b08522..bfb59a68e4fd 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -91,13 +91,13 @@ static void mark_open_files_invalid(struct cifsTconInfo *pTcon) struct list_head *tmp1; /* list all files open on tree connection and mark them invalid */ - write_lock(&GlobalSMBSeslock); + spin_lock(&cifs_file_list_lock); list_for_each_safe(tmp, tmp1, &pTcon->openFileList) { open_file = list_entry(tmp, struct cifsFileInfo, tlist); open_file->invalidHandle = true; open_file->oplock_break_cancelled = true; } - write_unlock(&GlobalSMBSeslock); + spin_unlock(&cifs_file_list_lock); /* BB Add call to invalidate_inodes(sb) for all superblocks mounted to this tcon */ } diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 293e9b767621..26048dc9069a 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -246,14 +246,14 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file, atomic_set(&pCifsFile->count, 1); INIT_WORK(&pCifsFile->oplock_break, cifs_oplock_break); - write_lock(&GlobalSMBSeslock); + spin_lock(&cifs_file_list_lock); list_add(&pCifsFile->tlist, &(tlink_tcon(tlink)->openFileList)); /* if readable file instance put first in list*/ if (file->f_mode & FMODE_READ) list_add(&pCifsFile->flist, &pCifsInode->openFileList); else list_add_tail(&pCifsFile->flist, &pCifsInode->openFileList); - write_unlock(&GlobalSMBSeslock); + spin_unlock(&cifs_file_list_lock); if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { pCifsInode->clientCanCacheAll = true; @@ -607,13 +607,13 @@ int cifs_close(struct inode *inode, struct file *file) pTcon = tlink_tcon(pSMBFile->tlink); if (pSMBFile) { struct cifsLockInfo *li, *tmp; - write_lock(&GlobalSMBSeslock); + spin_lock(&cifs_file_list_lock); pSMBFile->closePend = true; if (pTcon) { /* no sense reconnecting to close a file that is already closed */ if (!pTcon->need_reconnect) { - write_unlock(&GlobalSMBSeslock); + spin_unlock(&cifs_file_list_lock); timeout = 2; while ((atomic_read(&pSMBFile->count) != 1) && (timeout <= 2048)) { @@ -633,9 +633,9 @@ int cifs_close(struct inode *inode, struct file *file) rc = CIFSSMBClose(xid, pTcon, pSMBFile->netfid); } else - write_unlock(&GlobalSMBSeslock); + spin_unlock(&cifs_file_list_lock); } else - write_unlock(&GlobalSMBSeslock); + spin_unlock(&cifs_file_list_lock); /* Delete any outstanding lock records. We'll lose them when the file is closed anyway. */ @@ -646,16 +646,16 @@ int cifs_close(struct inode *inode, struct file *file) } mutex_unlock(&pSMBFile->lock_mutex); - write_lock(&GlobalSMBSeslock); + spin_lock(&cifs_file_list_lock); list_del(&pSMBFile->flist); list_del(&pSMBFile->tlist); - write_unlock(&GlobalSMBSeslock); + spin_unlock(&cifs_file_list_lock); cifsFileInfo_put(file->private_data); file->private_data = NULL; } else rc = -EBADF; - read_lock(&GlobalSMBSeslock); + spin_lock(&cifs_file_list_lock); if (list_empty(&(CIFS_I(inode)->openFileList))) { cFYI(1, "closing last open instance for inode %p", inode); /* if the file is not open we do not know if we can cache info @@ -663,7 +663,7 @@ int cifs_close(struct inode *inode, struct file *file) CIFS_I(inode)->clientCanCacheRead = false; CIFS_I(inode)->clientCanCacheAll = false; } - read_unlock(&GlobalSMBSeslock); + spin_unlock(&cifs_file_list_lock); if ((rc == 0) && CIFS_I(inode)->write_behind_rc) rc = CIFS_I(inode)->write_behind_rc; FreeXid(xid); @@ -685,18 +685,18 @@ int cifs_closedir(struct inode *inode, struct file *file) struct cifsTconInfo *pTcon = tlink_tcon(pCFileStruct->tlink); cFYI(1, "Freeing private data in close dir"); - write_lock(&GlobalSMBSeslock); + spin_lock(&cifs_file_list_lock); if (!pCFileStruct->srch_inf.endOfSearch && !pCFileStruct->invalidHandle) { pCFileStruct->invalidHandle = true; - write_unlock(&GlobalSMBSeslock); + spin_unlock(&cifs_file_list_lock); rc = CIFSFindClose(xid, pTcon, pCFileStruct->netfid); cFYI(1, "Closing uncompleted readdir with rc %d", rc); /* not much we can do if it fails anyway, ignore rc */ rc = 0; } else - write_unlock(&GlobalSMBSeslock); + spin_unlock(&cifs_file_list_lock); ptmp = pCFileStruct->srch_inf.ntwrk_buf_start; if (ptmp) { cFYI(1, "closedir free smb buf in srch struct"); @@ -1182,7 +1182,7 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) fsuid_only = false; - read_lock(&GlobalSMBSeslock); + spin_lock(&cifs_file_list_lock); /* we could simply get the first_list_entry since write-only entries are always at the end of the list but since the first entry might have a close pending, we go through the whole list */ @@ -1196,7 +1196,7 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, /* found a good file */ /* lock it so it will not be closed on us */ cifsFileInfo_get(open_file); - read_unlock(&GlobalSMBSeslock); + spin_unlock(&cifs_file_list_lock); return open_file; } /* else might as well continue, and look for another, or simply have the caller reopen it @@ -1204,7 +1204,7 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, } else /* write only file */ break; /* write only files are last so must be done */ } - read_unlock(&GlobalSMBSeslock); + spin_unlock(&cifs_file_list_lock); return NULL; } #endif @@ -1231,7 +1231,7 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) fsuid_only = false; - read_lock(&GlobalSMBSeslock); + spin_lock(&cifs_file_list_lock); refind_writable: list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { if (open_file->closePend) @@ -1245,11 +1245,11 @@ refind_writable: if (!open_file->invalidHandle) { /* found a good writable file */ - read_unlock(&GlobalSMBSeslock); + spin_unlock(&cifs_file_list_lock); return open_file; } - read_unlock(&GlobalSMBSeslock); + spin_unlock(&cifs_file_list_lock); /* Had to unlock since following call can block */ rc = cifs_reopen_file(open_file, false); if (!rc) { @@ -1257,7 +1257,7 @@ refind_writable: return open_file; else { /* start over in case this was deleted */ /* since the list could be modified */ - read_lock(&GlobalSMBSeslock); + spin_lock(&cifs_file_list_lock); cifsFileInfo_put(open_file); goto refind_writable; } @@ -1271,7 +1271,7 @@ refind_writable: to hold up writepages here (rather than in caller) with continuous retries */ cFYI(1, "wp failed on reopen file"); - read_lock(&GlobalSMBSeslock); + spin_lock(&cifs_file_list_lock); /* can not use this handle, no write pending on this one after all */ cifsFileInfo_put(open_file); @@ -1292,7 +1292,7 @@ refind_writable: any_available = true; goto refind_writable; } - read_unlock(&GlobalSMBSeslock); + spin_unlock(&cifs_file_list_lock); return NULL; } @@ -2200,16 +2200,16 @@ static int is_inode_writable(struct cifsInodeInfo *cifs_inode) { struct cifsFileInfo *open_file; - read_lock(&GlobalSMBSeslock); + spin_lock(&cifs_file_list_lock); list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { if (open_file->closePend) continue; if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) { - read_unlock(&GlobalSMBSeslock); + spin_unlock(&cifs_file_list_lock); return 1; } } - read_unlock(&GlobalSMBSeslock); + spin_unlock(&cifs_file_list_lock); return 0; } @@ -2373,8 +2373,8 @@ void cifs_oplock_break(struct work_struct *work) * finished grabbing reference for us. Make sure it's done by * waiting for GlobalSMSSeslock. */ - write_lock(&GlobalSMBSeslock); - write_unlock(&GlobalSMBSeslock); + spin_lock(&cifs_file_list_lock); + spin_unlock(&cifs_file_list_lock); cifs_oplock_break_put(cfile); } diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 9bac3e74b314..de6073cccd9c 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -560,7 +560,7 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) continue; cifs_stats_inc(&tcon->num_oplock_brks); - read_lock(&GlobalSMBSeslock); + spin_lock(&cifs_file_list_lock); list_for_each(tmp2, &tcon->openFileList) { netfile = list_entry(tmp2, struct cifsFileInfo, tlist); @@ -572,7 +572,7 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) * closed anyway. */ if (netfile->closePend) { - read_unlock(&GlobalSMBSeslock); + spin_unlock(&cifs_file_list_lock); read_unlock(&cifs_tcp_ses_lock); return true; } @@ -594,11 +594,11 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) cifs_oplock_break_get(netfile); netfile->oplock_break_cancelled = false; - read_unlock(&GlobalSMBSeslock); + spin_unlock(&cifs_file_list_lock); read_unlock(&cifs_tcp_ses_lock); return true; } - read_unlock(&GlobalSMBSeslock); + spin_unlock(&cifs_file_list_lock); read_unlock(&cifs_tcp_ses_lock); cFYI(1, "No matching file for oplock break"); return true; diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 6f3d13ff9470..ef7bb7b50f58 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -528,14 +528,14 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, (index_to_find < first_entry_in_buffer)) { /* close and restart search */ cFYI(1, "search backing up - close and restart search"); - write_lock(&GlobalSMBSeslock); + spin_lock(&cifs_file_list_lock); if (!cifsFile->srch_inf.endOfSearch && !cifsFile->invalidHandle) { cifsFile->invalidHandle = true; - write_unlock(&GlobalSMBSeslock); + spin_unlock(&cifs_file_list_lock); CIFSFindClose(xid, pTcon, cifsFile->netfid); } else - write_unlock(&GlobalSMBSeslock); + spin_unlock(&cifs_file_list_lock); if (cifsFile->srch_inf.ntwrk_buf_start) { cFYI(1, "freeing SMB ff cache buf on search rewind"); if (cifsFile->srch_inf.smallBuf) -- cgit v1.2.3-59-g8ed1b From 3f9bcca7820a6711307b6499952b13cfcfc31dd6 Mon Sep 17 00:00:00 2001 From: Suresh Jayaraman Date: Mon, 18 Oct 2010 23:29:37 +0530 Subject: cifs: convert cifs_tcp_ses_lock from a rwlock to a spinlock cifs_tcp_ses_lock is a rwlock with protects the cifs_tcp_ses_list, server->smb_ses_list and the ses->tcon_list. It also protects a few ref counters in server, ses and tcon. In most cases the critical section doesn't seem to be large, in a few cases where it is slightly large, there seem to be really no benefit from concurrent access. I briefly considered RCU mechanism but it appears to me that there is no real need. Replace it with a spinlock and get rid of the last rwlock in the cifs code. Signed-off-by: Suresh Jayaraman Signed-off-by: Steve French --- fs/cifs/cifs_debug.c | 12 ++++----- fs/cifs/cifsfs.c | 8 +++--- fs/cifs/cifsglob.h | 2 +- fs/cifs/cifssmb.c | 6 ++--- fs/cifs/connect.c | 70 ++++++++++++++++++++++++++-------------------------- fs/cifs/misc.c | 14 +++++------ fs/cifs/sess.c | 4 +-- 7 files changed, 58 insertions(+), 58 deletions(-) (limited to 'fs/cifs/cifsfs.c') diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index eb1ba493489f..103ab8b605b0 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c @@ -148,7 +148,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) seq_printf(m, "Servers:"); i = 0; - read_lock(&cifs_tcp_ses_lock); + spin_lock(&cifs_tcp_ses_lock); list_for_each(tmp1, &cifs_tcp_ses_list) { server = list_entry(tmp1, struct TCP_Server_Info, tcp_ses_list); @@ -230,7 +230,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) spin_unlock(&GlobalMid_Lock); } } - read_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); seq_putc(m, '\n'); /* BB add code to dump additional info such as TCP session info now */ @@ -270,7 +270,7 @@ static ssize_t cifs_stats_proc_write(struct file *file, atomic_set(&totBufAllocCount, 0); atomic_set(&totSmBufAllocCount, 0); #endif /* CONFIG_CIFS_STATS2 */ - read_lock(&cifs_tcp_ses_lock); + spin_lock(&cifs_tcp_ses_lock); list_for_each(tmp1, &cifs_tcp_ses_list) { server = list_entry(tmp1, struct TCP_Server_Info, tcp_ses_list); @@ -303,7 +303,7 @@ static ssize_t cifs_stats_proc_write(struct file *file, } } } - read_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); } return count; @@ -343,7 +343,7 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v) GlobalCurrentXid, GlobalMaxActiveXid); i = 0; - read_lock(&cifs_tcp_ses_lock); + spin_lock(&cifs_tcp_ses_lock); list_for_each(tmp1, &cifs_tcp_ses_list) { server = list_entry(tmp1, struct TCP_Server_Info, tcp_ses_list); @@ -397,7 +397,7 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v) } } } - read_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); seq_putc(m, '\n'); return 0; diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index f1d9c71e807f..cb77915a445b 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -482,16 +482,16 @@ static void cifs_umount_begin(struct super_block *sb) tcon = cifs_sb_master_tcon(cifs_sb); - read_lock(&cifs_tcp_ses_lock); + spin_lock(&cifs_tcp_ses_lock); if ((tcon->tc_count > 1) || (tcon->tidStatus == CifsExiting)) { /* we have other mounts to same share or we have already tried to force umount this and woken up all waiting network requests, nothing to do */ - read_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); return; } else if (tcon->tc_count == 1) tcon->tidStatus = CifsExiting; - read_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */ /* cancel_notify_requests(tcon); */ @@ -940,7 +940,7 @@ init_cifs(void) GlobalTotalActiveXid = 0; GlobalMaxActiveXid = 0; memset(Local_System_Name, 0, 15); - rwlock_init(&cifs_tcp_ses_lock); + spin_lock_init(&cifs_tcp_ses_lock); spin_lock_init(&cifs_file_list_lock); spin_lock_init(&GlobalMid_Lock); diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 18ee0adda306..28337cba0295 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -703,7 +703,7 @@ GLOBAL_EXTERN struct list_head cifs_tcp_ses_list; * the reference counters for the server, smb session, and tcon. Finally, * changes to the tcon->tidStatus should be done while holding this lock. */ -GLOBAL_EXTERN rwlock_t cifs_tcp_ses_lock; +GLOBAL_EXTERN spinlock_t cifs_tcp_ses_lock; /* * This lock protects the cifs_file->llist and cifs_file->flist diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index bfb59a68e4fd..e98f1f317b15 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -593,9 +593,9 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) rc = -EIO; goto neg_err_exit; } - read_lock(&cifs_tcp_ses_lock); + spin_lock(&cifs_tcp_ses_lock); if (server->srv_count > 1) { - read_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); if (memcmp(server->server_GUID, pSMBr->u.extended_response. GUID, 16) != 0) { @@ -605,7 +605,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) 16); } } else { - read_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); memcpy(server->server_GUID, pSMBr->u.extended_response.GUID, 16); } diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 019f00380d12..7e73176acb58 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -150,7 +150,7 @@ cifs_reconnect(struct TCP_Server_Info *server) /* before reconnecting the tcp session, mark the smb session (uid) and the tid bad so they are not used until reconnected */ - read_lock(&cifs_tcp_ses_lock); + spin_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; @@ -160,7 +160,7 @@ cifs_reconnect(struct TCP_Server_Info *server) tcon->need_reconnect = true; } } - read_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); /* do not want to be sending data on a socket we are freeing */ mutex_lock(&server->srv_mutex); if (server->ssocket) { @@ -637,9 +637,9 @@ multi_t2_fnd: } /* end while !EXITING */ /* take it off the list, if it's not already */ - write_lock(&cifs_tcp_ses_lock); + spin_lock(&cifs_tcp_ses_lock); list_del_init(&server->tcp_ses_list); - write_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); spin_lock(&GlobalMid_Lock); server->tcpStatus = CifsExiting; @@ -677,7 +677,7 @@ multi_t2_fnd: * 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); + spin_lock(&cifs_tcp_ses_lock); if (list_empty(&server->pending_mid_q)) { /* loop through server session structures attached to this and mark them dead */ @@ -687,7 +687,7 @@ multi_t2_fnd: ses->status = CifsExiting; ses->server = NULL; } - read_unlock(&cifs_tcp_ses_lock); + spin_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, @@ -710,7 +710,7 @@ multi_t2_fnd: } } spin_unlock(&GlobalMid_Lock); - read_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); /* 1/8th of sec is more than enough time for them to exit */ msleep(125); } @@ -733,12 +733,12 @@ multi_t2_fnd: if a crazy root user tried to kill cifsd kernel thread explicitly this might happen) */ /* BB: This shouldn't be necessary, see above */ - read_lock(&cifs_tcp_ses_lock); + spin_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; } - read_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); kfree(server->hostname); task_to_wake = xchg(&server->tsk, NULL); @@ -1524,7 +1524,7 @@ cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol) { struct TCP_Server_Info *server; - write_lock(&cifs_tcp_ses_lock); + spin_lock(&cifs_tcp_ses_lock); list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) { if (!match_address(server, addr, (struct sockaddr *)&vol->srcaddr)) @@ -1534,11 +1534,11 @@ cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol) continue; ++server->srv_count; - write_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); cFYI(1, "Existing tcp session with server found"); return server; } - write_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); return NULL; } @@ -1547,14 +1547,14 @@ cifs_put_tcp_session(struct TCP_Server_Info *server) { struct task_struct *task; - write_lock(&cifs_tcp_ses_lock); + spin_lock(&cifs_tcp_ses_lock); if (--server->srv_count > 0) { - write_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); return; } list_del_init(&server->tcp_ses_list); - write_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); spin_lock(&GlobalMid_Lock); server->tcpStatus = CifsExiting; @@ -1679,9 +1679,9 @@ cifs_get_tcp_session(struct smb_vol *volume_info) } /* thread spawned, put it on the list */ - write_lock(&cifs_tcp_ses_lock); + spin_lock(&cifs_tcp_ses_lock); list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list); - write_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); cifs_fscache_get_client_cookie(tcp_ses); @@ -1703,7 +1703,7 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol) { struct cifsSesInfo *ses; - write_lock(&cifs_tcp_ses_lock); + spin_lock(&cifs_tcp_ses_lock); list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { switch (server->secType) { case Kerberos: @@ -1723,10 +1723,10 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol) continue; } ++ses->ses_count; - write_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); return ses; } - write_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); return NULL; } @@ -1737,14 +1737,14 @@ cifs_put_smb_ses(struct cifsSesInfo *ses) struct TCP_Server_Info *server = ses->server; cFYI(1, "%s: ses_count=%d\n", __func__, ses->ses_count); - write_lock(&cifs_tcp_ses_lock); + spin_lock(&cifs_tcp_ses_lock); if (--ses->ses_count > 0) { - write_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); return; } list_del_init(&ses->smb_ses_list); - write_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); if (ses->status == CifsGood) { xid = GetXid(); @@ -1841,9 +1841,9 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) goto get_ses_fail; /* success, put it on the list */ - write_lock(&cifs_tcp_ses_lock); + spin_lock(&cifs_tcp_ses_lock); list_add(&ses->smb_ses_list, &server->smb_ses_list); - write_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); FreeXid(xid); return ses; @@ -1860,7 +1860,7 @@ cifs_find_tcon(struct cifsSesInfo *ses, const char *unc) struct list_head *tmp; struct cifsTconInfo *tcon; - write_lock(&cifs_tcp_ses_lock); + spin_lock(&cifs_tcp_ses_lock); list_for_each(tmp, &ses->tcon_list) { tcon = list_entry(tmp, struct cifsTconInfo, tcon_list); if (tcon->tidStatus == CifsExiting) @@ -1869,10 +1869,10 @@ cifs_find_tcon(struct cifsSesInfo *ses, const char *unc) continue; ++tcon->tc_count; - write_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); return tcon; } - write_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); return NULL; } @@ -1883,14 +1883,14 @@ cifs_put_tcon(struct cifsTconInfo *tcon) struct cifsSesInfo *ses = tcon->ses; cFYI(1, "%s: tc_count=%d\n", __func__, tcon->tc_count); - write_lock(&cifs_tcp_ses_lock); + spin_lock(&cifs_tcp_ses_lock); if (--tcon->tc_count > 0) { - write_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); return; } list_del_init(&tcon->tcon_list); - write_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); xid = GetXid(); CIFSSMBTDis(xid, tcon); @@ -1963,9 +1963,9 @@ cifs_get_tcon(struct cifsSesInfo *ses, struct smb_vol *volume_info) tcon->nocase = volume_info->nocase; tcon->local_lease = volume_info->local_lease; - write_lock(&cifs_tcp_ses_lock); + spin_lock(&cifs_tcp_ses_lock); list_add(&tcon->tcon_list, &ses->tcon_list); - write_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); cifs_fscache_get_super_cookie(tcon); @@ -3225,9 +3225,9 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid) vol_info->secFlg = CIFSSEC_MUST_KRB5; /* get a reference for the same TCP session */ - write_lock(&cifs_tcp_ses_lock); + spin_lock(&cifs_tcp_ses_lock); ++master_tcon->ses->server->srv_count; - write_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info); if (IS_ERR(ses)) { diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index de6073cccd9c..a7b492c213cd 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -347,7 +347,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , if (current_fsuid() != treeCon->ses->linux_uid) { cFYI(1, "Multiuser mode and UID " "did not match tcon uid"); - read_lock(&cifs_tcp_ses_lock); + spin_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()) { @@ -361,7 +361,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , } } } - read_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); } } } @@ -551,7 +551,7 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) return false; /* look up tcon based on tid & uid */ - read_lock(&cifs_tcp_ses_lock); + spin_lock(&cifs_tcp_ses_lock); list_for_each(tmp, &srv->smb_ses_list) { ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list); list_for_each(tmp1, &ses->tcon_list) { @@ -573,7 +573,7 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) */ if (netfile->closePend) { spin_unlock(&cifs_file_list_lock); - read_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); return true; } @@ -595,16 +595,16 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) netfile->oplock_break_cancelled = false; spin_unlock(&cifs_file_list_lock); - read_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); return true; } spin_unlock(&cifs_file_list_lock); - read_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); cFYI(1, "No matching file for oplock break"); return true; } } - read_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); cFYI(1, "Can not process oplock break for non-existent connection"); return true; } diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index e35dc60d3255..2a11efd96592 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c @@ -80,7 +80,7 @@ static __le16 get_next_vcnum(struct cifsSesInfo *ses) if (max_vcs < 2) max_vcs = 0xFFFF; - write_lock(&cifs_tcp_ses_lock); + spin_lock(&cifs_tcp_ses_lock); if ((ses->need_reconnect) && is_first_ses_reconnect(ses)) goto get_vc_num_exit; /* vcnum will be zero */ for (i = ses->server->srv_count - 1; i < max_vcs; i++) { @@ -112,7 +112,7 @@ static __le16 get_next_vcnum(struct cifsSesInfo *ses) vcnum = i; ses->vcnum = vcnum; get_vc_num_exit: - write_unlock(&cifs_tcp_ses_lock); + spin_unlock(&cifs_tcp_ses_lock); return cpu_to_le16(vcnum); } -- cgit v1.2.3-59-g8ed1b