diff options
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/cifsfs.c | 17 | ||||
-rw-r--r-- | fs/cifs/connect.c | 1 | ||||
-rw-r--r-- | fs/cifs/file.c | 8 | ||||
-rw-r--r-- | fs/cifs/inode.c | 10 | ||||
-rw-r--r-- | fs/cifs/link.c | 33 | ||||
-rw-r--r-- | fs/cifs/misc.c | 4 | ||||
-rw-r--r-- | fs/cifs/sess.c | 23 | ||||
-rw-r--r-- | fs/cifs/transport.c | 6 |
8 files changed, 66 insertions, 36 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 84976cdbe713..71bc87a37fc1 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -34,6 +34,7 @@ #include <linux/mempool.h> #include <linux/delay.h> #include <linux/kthread.h> +#include <linux/freezer.h> #include "cifsfs.h" #include "cifspdu.h" #define DECLARE_GLOBALS_HERE @@ -81,7 +82,7 @@ extern mempool_t *cifs_sm_req_poolp; extern mempool_t *cifs_req_poolp; extern mempool_t *cifs_mid_poolp; -extern kmem_cache_t *cifs_oplock_cachep; +extern struct kmem_cache *cifs_oplock_cachep; static int cifs_read_super(struct super_block *sb, void *data, @@ -232,11 +233,11 @@ static int cifs_permission(struct inode * inode, int mask, struct nameidata *nd) return generic_permission(inode, mask, NULL); } -static kmem_cache_t *cifs_inode_cachep; -static kmem_cache_t *cifs_req_cachep; -static kmem_cache_t *cifs_mid_cachep; -kmem_cache_t *cifs_oplock_cachep; -static kmem_cache_t *cifs_sm_req_cachep; +static struct kmem_cache *cifs_inode_cachep; +static struct kmem_cache *cifs_req_cachep; +static struct kmem_cache *cifs_mid_cachep; +struct kmem_cache *cifs_oplock_cachep; +static struct kmem_cache *cifs_sm_req_cachep; mempool_t *cifs_sm_req_poolp; mempool_t *cifs_req_poolp; mempool_t *cifs_mid_poolp; @@ -245,7 +246,7 @@ static struct inode * cifs_alloc_inode(struct super_block *sb) { struct cifsInodeInfo *cifs_inode; - cifs_inode = kmem_cache_alloc(cifs_inode_cachep, SLAB_KERNEL); + cifs_inode = kmem_cache_alloc(cifs_inode_cachep, GFP_KERNEL); if (!cifs_inode) return NULL; cifs_inode->cifsAttrs = 0x20; /* default */ @@ -668,7 +669,7 @@ const struct file_operations cifs_dir_ops = { }; static void -cifs_init_once(void *inode, kmem_cache_t * cachep, unsigned long flags) +cifs_init_once(void *inode, struct kmem_cache * cachep, unsigned long flags) { struct cifsInodeInfo *cifsi = inode; diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 71f77914ce93..2caca06b4bae 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -31,6 +31,7 @@ #include <linux/delay.h> #include <linux/completion.h> #include <linux/pagevec.h> +#include <linux/freezer.h> #include <asm/uaccess.h> #include <asm/processor.h> #include "cifspdu.h" diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 7e056b9b49e8..2436ed8fc840 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -492,10 +492,14 @@ int cifs_close(struct inode *inode, struct file *file) the struct would be in each open file, but this should give enough time to clear the socket */ - cERROR(1,("close with pending writes")); +#ifdef CONFIG_CIFS_DEBUG2 + cFYI(1,("close delay, write pending")); +#endif /* DEBUG2 */ msleep(timeout); timeout *= 4; - } + } + if(atomic_read(&pSMBFile->wrtPending)) + cERROR(1,("close with pending writes")); rc = CIFSSMBClose(xid, pTcon, pSMBFile->netfid); } diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index dffe295825f4..c4fa91b8b62f 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -318,6 +318,7 @@ int cifs_get_inode_info(struct inode **pinode, struct cifs_sb_info *cifs_sb = CIFS_SB(sb); char *tmp_path; char *buf = NULL; + int adjustTZ = FALSE; pTcon = cifs_sb->tcon; cFYI(1,("Getting info on %s", search_path)); @@ -348,6 +349,7 @@ int cifs_get_inode_info(struct inode **pinode, pfindData, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); + adjustTZ = TRUE; } } @@ -444,6 +446,10 @@ int cifs_get_inode_info(struct inode **pinode, inode->i_ctime = cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); cFYI(0, ("Attributes came in as 0x%x", attr)); + if(adjustTZ && (pTcon->ses) && (pTcon->ses->server)) { + inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj; + inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj; + } /* set default mode. will override for dirs below */ if (atomic_read(&cifsInfo->inUse) == 0) @@ -1089,8 +1095,10 @@ int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) { int err = cifs_revalidate(dentry); - if (!err) + if (!err) { generic_fillattr(dentry->d_inode, stat); + stat->blksize = CIFS_MAX_MSGSIZE; + } return err; } diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 0bee8b7e521a..8e259969354b 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c @@ -69,17 +69,30 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode, rc = -EOPNOTSUPP; } -/* if (!rc) */ - { - /* renew_parental_timestamps(old_file); - inode->i_nlink++; - mark_inode_dirty(inode); - d_instantiate(direntry, inode); */ - /* BB add call to either mark inode dirty or refresh its data and timestamp to current time */ + d_drop(direntry); /* force new lookup from server of target */ + + /* if source file is cached (oplocked) revalidate will not go to server + until the file is closed or oplock broken so update nlinks locally */ + if(old_file->d_inode) { + cifsInode = CIFS_I(old_file->d_inode); + if(rc == 0) { + old_file->d_inode->i_nlink++; + old_file->d_inode->i_ctime = CURRENT_TIME; + /* parent dir timestamps will update from srv + within a second, would it really be worth it + to set the parent dir cifs inode time to zero + to force revalidate (faster) for it too? */ + } + /* if not oplocked will force revalidate to get info + on source file from srv */ + cifsInode->time = 0; + + /* Will update parent dir timestamps from srv within a second. + Would it really be worth it to set the parent dir (cifs + inode) time field to zero to force revalidate on parent + directory faster ie + CIFS_I(inode)->time = 0; */ } - d_drop(direntry); /* force new lookup from server */ - cifsInode = CIFS_I(old_file->d_inode); - cifsInode->time = 0; /* will force revalidate to go get info when needed */ cifs_hl_exit: kfree(fromName); diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index bbc9cd34b6ea..aedf683f011f 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -153,7 +153,7 @@ cifs_buf_get(void) albeit slightly larger than necessary and maxbuffersize defaults to this and can not be bigger */ ret_buf = - (struct smb_hdr *) mempool_alloc(cifs_req_poolp, SLAB_KERNEL | SLAB_NOFS); + (struct smb_hdr *) mempool_alloc(cifs_req_poolp, GFP_KERNEL | GFP_NOFS); /* clear the first few header bytes */ /* for most paths, more is cleared in header_assemble */ @@ -192,7 +192,7 @@ cifs_small_buf_get(void) albeit slightly larger than necessary and maxbuffersize defaults to this and can not be bigger */ ret_buf = - (struct smb_hdr *) mempool_alloc(cifs_sm_req_poolp, SLAB_KERNEL | SLAB_NOFS); + (struct smb_hdr *) mempool_alloc(cifs_sm_req_poolp, GFP_KERNEL | GFP_NOFS); if (ret_buf) { /* No need to clear memory here, cleared in header assemble */ /* memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);*/ diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index a8a083543ba0..bbdda99dce61 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c @@ -90,7 +90,9 @@ static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses, } */ /* copy user */ if(ses->userName == NULL) { - /* BB what about null user mounts - check that we do this BB */ + /* null user mount */ + *bcc_ptr = 0; + *(bcc_ptr+1) = 0; } else { /* 300 should be long enough for any conceivable user name */ bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->userName, 300, nls_cp); @@ -98,10 +100,13 @@ static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses, bcc_ptr += 2 * bytes_ret; bcc_ptr += 2; /* account for null termination */ /* copy domain */ - if(ses->domainName == NULL) - bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, - "CIFS_LINUX_DOM", 32, nls_cp); - else + if(ses->domainName == NULL) { + /* Sending null domain better than using a bogus domain name (as + we did briefly in 2.6.18) since server will use its default */ + *bcc_ptr = 0; + *(bcc_ptr+1) = 0; + bytes_ret = 0; + } else bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName, 256, nls_cp); bcc_ptr += 2 * bytes_ret; @@ -144,13 +149,11 @@ static void ascii_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses, /* copy domain */ - if(ses->domainName == NULL) { - strcpy(bcc_ptr, "CIFS_LINUX_DOM"); - bcc_ptr += 14; /* strlen(CIFS_LINUX_DOM) */ - } else { + if(ses->domainName != NULL) { strncpy(bcc_ptr, ses->domainName, 256); bcc_ptr += strnlen(ses->domainName, 256); - } + } /* else we will send a null domain name + so the server will default to its own domain */ *bcc_ptr = 0; bcc_ptr++; diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 48d47b46b1fb..f80007eaebf4 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -34,7 +34,7 @@ #include "cifs_debug.h" extern mempool_t *cifs_mid_poolp; -extern kmem_cache_t *cifs_oplock_cachep; +extern struct kmem_cache *cifs_oplock_cachep; static struct mid_q_entry * AllocMidQEntry(const struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) @@ -51,7 +51,7 @@ AllocMidQEntry(const struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) } temp = (struct mid_q_entry *) mempool_alloc(cifs_mid_poolp, - SLAB_KERNEL | SLAB_NOFS); + GFP_KERNEL | GFP_NOFS); if (temp == NULL) return temp; else { @@ -118,7 +118,7 @@ AllocOplockQEntry(struct inode * pinode, __u16 fid, struct cifsTconInfo * tcon) return NULL; } temp = (struct oplock_q_entry *) kmem_cache_alloc(cifs_oplock_cachep, - SLAB_KERNEL); + GFP_KERNEL); if (temp == NULL) return temp; else { |