]> Pileus Git - ~andy/linux/commitdiff
Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
authorSteve French <sfrench@us.ibm.com>
Fri, 31 Mar 2006 03:35:56 +0000 (03:35 +0000)
committerSteve French <sfrench@us.ibm.com>
Fri, 31 Mar 2006 03:35:56 +0000 (03:35 +0000)
Signed-off-by: Steve French <sfrench@us.ibm.com>
1  2 
fs/cifs/CHANGES
fs/cifs/cifsfs.c
fs/cifs/cifsfs.h
fs/cifs/cifssmb.c
fs/cifs/dir.c
fs/cifs/file.c
fs/cifs/inode.c
fs/cifs/link.c
fs/cifs/readdir.c

diff --combined fs/cifs/CHANGES
index 3e0fcc394810d598f0ca4ae5775e8f31ad24a911,cb68efba35dbb82750b9e915b19177adc4e4ebf6..8a2de038882e32bb881e53c92171e5967e073a42
@@@ -1,21 -1,3 +1,21 @@@
 +Version 1.42
 +------------
 +Fix slow oplock break when mounted to different servers at the same time and
 +the tids match and we try to find matching fid on wrong server.
 +
 +Version 1.41
 +------------
 +Fix NTLMv2 security (can be enabled in /proc/fs/cifs) so customers can
 +configure stronger authentication.  Fix sfu symlinks so they can
 +be followed (not just recognized).  Fix wraparound of bcc on
 +read responses when buffer size over 64K and also fix wrap of
 +max smb buffer size when CIFSMaxBufSize over 64K.  Fix oops in
 +cifs_user_read and cifs_readpages (when EAGAIN on send of smb
 +on socket is returned over and over).  Add POSIX (advisory) byte range
 +locking support (requires server with newest CIFS UNIX Extensions
 +to the protocol implemented). Slow down negprot slightly in port 139
 +RFC1001 case to give session_init time on buggy servers.
 +
  Version 1.40
  ------------
  Use fsuid (fsgid) more consistently instead of uid (gid). Improve performance
@@@ -178,7 -160,7 +178,7 @@@ improperly zeroed buffer in CIFS Unix e
  Version 1.25
  ------------
  Fix internationalization problem in cifs readdir with filenames that map to 
- longer UTF8 strings than the string on the wire was in Unicode.  Add workaround
+ longer UTF-8 strings than the string on the wire was in Unicode.  Add workaround
  for readdir to netapp servers. Fix search rewind (seek into readdir to return 
  non-consecutive entries).  Do not do readdir when server negotiates 
  buffer size to small to fit filename. Add support for reading POSIX ACLs from
diff --combined fs/cifs/cifsfs.c
index 8219c02145a7e8f1e619e4e3bf7cdee9d25b9251,4bbc544857bccf160405121a8719d89736ed1699..d4b713e5affbdd86e7050f343173897336071e40
@@@ -93,10 -93,13 +93,10 @@@ cifs_read_super(struct super_block *sb
        int rc = 0;
  
        sb->s_flags |= MS_NODIRATIME; /* and probably even noatime */
 -      sb->s_fs_info = kmalloc(sizeof(struct cifs_sb_info),GFP_KERNEL);
 +      sb->s_fs_info = kzalloc(sizeof(struct cifs_sb_info),GFP_KERNEL);
        cifs_sb = CIFS_SB(sb);
        if(cifs_sb == NULL)
                return -ENOMEM;
 -      else
 -              memset(cifs_sb,0,sizeof(struct cifs_sb_info));
 -      
  
        rc = cifs_mount(sb, cifs_sb, data, devname);
  
@@@ -476,7 -479,7 +476,7 @@@ cifs_get_sb(struct file_system_type *fs
  
        sb->s_flags = flags;
  
-       rc = cifs_read_super(sb, data, dev_name, flags & MS_VERBOSE ? 1 : 0);
+       rc = cifs_read_super(sb, data, dev_name, flags & MS_SILENT ? 1 : 0);
        if (rc) {
                up_write(&sb->s_umount);
                deactivate_super(sb);
@@@ -580,7 -583,7 +580,7 @@@ struct inode_operations cifs_symlink_in
  #endif 
  };
  
- struct file_operations cifs_file_ops = {
const struct file_operations cifs_file_ops = {
        .read = do_sync_read,
        .write = do_sync_write,
        .readv = generic_file_readv,
  #endif /* CONFIG_CIFS_EXPERIMENTAL */
  };
  
- struct file_operations cifs_file_direct_ops = {
const struct file_operations cifs_file_direct_ops = {
        /* no mmap, no aio, no readv - 
           BB reevaluate whether they can be done with directio, no cache */
        .read = cifs_user_read,
        .dir_notify = cifs_dir_notify,
  #endif /* CONFIG_CIFS_EXPERIMENTAL */
  };
- struct file_operations cifs_file_nobrl_ops = {
const struct file_operations cifs_file_nobrl_ops = {
        .read = do_sync_read,
        .write = do_sync_write,
        .readv = generic_file_readv,
  #endif /* CONFIG_CIFS_EXPERIMENTAL */
  };
  
- struct file_operations cifs_file_direct_nobrl_ops = {
const struct file_operations cifs_file_direct_nobrl_ops = {
        /* no mmap, no aio, no readv - 
           BB reevaluate whether they can be done with directio, no cache */
        .read = cifs_user_read,
  #endif /* CONFIG_CIFS_EXPERIMENTAL */
  };
  
- struct file_operations cifs_dir_ops = {
const struct file_operations cifs_dir_ops = {
        .readdir = cifs_readdir,
        .release = cifs_closedir,
        .read    = generic_read_dir,
@@@ -692,7 -695,8 +692,8 @@@ cifs_init_inodecache(void
  {
        cifs_inode_cachep = kmem_cache_create("cifs_inode_cache",
                                              sizeof (struct cifsInodeInfo),
-                                             0, SLAB_RECLAIM_ACCOUNT,
+                                             0, (SLAB_RECLAIM_ACCOUNT|
+                                               SLAB_MEM_SPREAD),
                                              cifs_init_once, NULL);
        if (cifs_inode_cachep == NULL)
                return -ENOMEM;
@@@ -734,10 -738,8 +735,8 @@@ cifs_init_request_bufs(void
                cERROR(1,("cifs_min_rcv set to maximum (64)"));
        }
  
-       cifs_req_poolp = mempool_create(cifs_min_rcv,
-                                       mempool_alloc_slab,
-                                       mempool_free_slab,
-                                       cifs_req_cachep);
+       cifs_req_poolp = mempool_create_slab_pool(cifs_min_rcv,
+                                                 cifs_req_cachep);
  
        if(cifs_req_poolp == NULL) {
                kmem_cache_destroy(cifs_req_cachep);
                cFYI(1,("cifs_min_small set to maximum (256)"));
        }
  
-       cifs_sm_req_poolp = mempool_create(cifs_min_small,
-                               mempool_alloc_slab,
-                               mempool_free_slab,
-                               cifs_sm_req_cachep);
+       cifs_sm_req_poolp = mempool_create_slab_pool(cifs_min_small,
+                                                    cifs_sm_req_cachep);
  
        if(cifs_sm_req_poolp == NULL) {
                mempool_destroy(cifs_req_poolp);
@@@ -804,10 -804,8 +801,8 @@@ cifs_init_mids(void
        if (cifs_mid_cachep == NULL)
                return -ENOMEM;
  
-       cifs_mid_poolp = mempool_create(3 /* a reasonable min simultan opers */,
-                                       mempool_alloc_slab,
-                                       mempool_free_slab,
-                                       cifs_mid_cachep);
+       /* 3 is a reasonable minimum number of simultaneous operations */
+       cifs_mid_poolp = mempool_create_slab_pool(3, cifs_mid_cachep);
        if(cifs_mid_poolp == NULL) {
                kmem_cache_destroy(cifs_mid_cachep);
                return -ENOMEM;
diff --combined fs/cifs/cifsfs.h
index b4dcdc2052a0e72f36d0b7106834c1818f9bcae6,74f405ae4da349e4a0224aece033cfb5dbb8ecaa..4e829dc672a645622c078466244a71d611c1e8c9
@@@ -61,10 -61,10 +61,10 @@@ extern struct inode_operations cifs_fil
  extern struct inode_operations cifs_symlink_inode_ops;
  
  /* Functions related to files and directories */
- extern struct file_operations cifs_file_ops;
- extern struct file_operations cifs_file_direct_ops; /* if directio mount */
- extern struct file_operations cifs_file_nobrl_ops;
- extern struct file_operations cifs_file_direct_nobrl_ops; /* if directio mount */
+ extern const struct file_operations cifs_file_ops;
+ extern const struct file_operations cifs_file_direct_ops; /* if directio mount */
+ extern const struct file_operations cifs_file_nobrl_ops;
+ extern const struct file_operations cifs_file_direct_nobrl_ops; /* if directio mount */
  extern int cifs_open(struct inode *inode, struct file *file);
  extern int cifs_close(struct inode *inode, struct file *file);
  extern int cifs_closedir(struct inode *inode, struct file *file);
@@@ -76,7 -76,7 +76,7 @@@ extern int cifs_lock(struct file *, int
  extern int cifs_fsync(struct file *, struct dentry *, int);
  extern int cifs_flush(struct file *);
  extern int cifs_file_mmap(struct file * , struct vm_area_struct *);
- extern struct file_operations cifs_dir_ops;
+ extern const struct file_operations cifs_dir_ops;
  extern int cifs_dir_open(struct inode *inode, struct file *file);
  extern int cifs_readdir(struct file *file, void *direntry, filldir_t filldir);
  extern int cifs_dir_notify(struct file *, unsigned long arg);
@@@ -99,5 -99,5 +99,5 @@@ extern ssize_t        cifs_getxattr(struct den
  extern ssize_t        cifs_listxattr(struct dentry *, char *, size_t);
  extern int cifs_ioctl (struct inode * inode, struct file * filep,
                       unsigned int command, unsigned long arg);
 -#define CIFS_VERSION   "1.40"
 +#define CIFS_VERSION   "1.42"
  #endif                                /* _CIFSFS_H */
diff --combined fs/cifs/cifssmb.c
index a5941872d3f753ee83ee0264e59d1b6b5ea20000,a243fe2792d5ed34824f56e8a0a3205d36e48ab5..d705500aa283ab7170f42d9ff654668d1b1ad6a6
@@@ -1,7 -1,7 +1,7 @@@
  /*
   *   fs/cifs/cifssmb.c
   *
 - *   Copyright (C) International Business Machines  Corp., 2002,2005
 + *   Copyright (C) International Business Machines  Corp., 2002,2006
   *   Author(s): Steve French (sfrench@us.ibm.com)
   *
   *   Contains the routines for constructing the SMB PDUs themselves
@@@ -186,35 -186,7 +186,35 @@@ small_smb_init(int smb_command, int wct
                  cifs_stats_inc(&tcon->num_smbs_sent);
  
        return rc;
 -}  
 +}
 +
 +#ifdef CONFIG_CIFS_EXPERIMENTAL  
 +int
 +small_smb_init_no_tc(const int smb_command, const int wct, 
 +                   struct cifsSesInfo *ses, void **request_buf)
 +{
 +      int rc;
 +      struct smb_hdr * buffer;
 +
 +      rc = small_smb_init(smb_command, wct, NULL, request_buf);
 +      if(rc)
 +              return rc;
 +
 +      buffer = (struct smb_hdr *)*request_buf;
 +      buffer->Mid = GetNextMid(ses->server);
 +      if (ses->capabilities & CAP_UNICODE)
 +              buffer->Flags2 |= SMBFLG2_UNICODE;
 +      if (ses->capabilities & CAP_STATUS32)
 +              buffer->Flags2 |= SMBFLG2_ERR_STATUS;
 +
 +      /* uid, tid can stay at zero as set in header assemble */
 +
 +      /* BB add support for turning on the signing when 
 +      this function is used after 1st of session setup requests */
 +
 +      return rc;
 +}
 +#endif  /* CONFIG_CIFS_EXPERIMENTAL */
  
  /* If the return code is zero, this function must fill in request_buf pointer */
  static int
@@@ -1070,7 -1042,7 +1070,7 @@@ CIFSSMBRead(const int xid, struct cifsT
                }
        }
  
 -      cifs_small_buf_release(pSMB);
 +/*    cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
        if(*buf) {
                if(resp_buf_type == CIFS_SMALL_BUFFER)
                        cifs_small_buf_release(iov[0].iov_base);
@@@ -1274,7 -1246,7 +1274,7 @@@ CIFSSMBWrite2(const int xid, struct cif
                *nbytes += le16_to_cpu(pSMBr->Count);
        } 
  
 -      cifs_small_buf_release(pSMB);
 +/*    cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
        if(resp_buf_type == CIFS_SMALL_BUFFER)
                cifs_small_buf_release(iov[0].iov_base);
        else if(resp_buf_type == CIFS_LARGE_BUFFER)
@@@ -1352,85 -1324,6 +1352,85 @@@ CIFSSMBLock(const int xid, struct cifsT
        return rc;
  }
  
 +int
 +CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
 +              const __u16 smb_file_id, const int get_flag, const __u64 len,
 +              const __u64 lkoffset, const __u16 lock_type, const int waitFlag)
 +{
 +      struct smb_com_transaction2_sfi_req *pSMB  = NULL;
 +      struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
 +      char *data_offset;
 +      struct cifs_posix_lock *parm_data;
 +      int rc = 0;
 +      int bytes_returned = 0;
 +      __u16 params, param_offset, offset, byte_count, count;
 +
 +      cFYI(1, ("Posix Lock"));
 +      rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
 +
 +      if (rc)
 +              return rc;
 +
 +      pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
 +
 +      params = 6; 
 +      pSMB->MaxSetupCount = 0;
 +      pSMB->Reserved = 0;
 +      pSMB->Flags = 0;
 +      pSMB->Timeout = 0;
 +      pSMB->Reserved2 = 0;
 +      param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
 +      offset = param_offset + params;
 +
 +      data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
 +
 +      count = sizeof(struct cifs_posix_lock);
 +      pSMB->MaxParameterCount = cpu_to_le16(2);
 +      pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */
 +      pSMB->SetupCount = 1;
 +      pSMB->Reserved3 = 0;
 +      if(get_flag)
 +              pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
 +      else
 +              pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
 +      byte_count = 3 /* pad */  + params + count;
 +      pSMB->DataCount = cpu_to_le16(count);
 +      pSMB->ParameterCount = cpu_to_le16(params);
 +      pSMB->TotalDataCount = pSMB->DataCount;
 +      pSMB->TotalParameterCount = pSMB->ParameterCount;
 +      pSMB->ParameterOffset = cpu_to_le16(param_offset);
 +      parm_data = (struct cifs_posix_lock *) 
 +                      (((char *) &pSMB->hdr.Protocol) + offset);
 +
 +      parm_data->lock_type = cpu_to_le16(lock_type);
 +      if(waitFlag)
 +              parm_data->lock_flags = 1;
 +      parm_data->pid = cpu_to_le32(current->tgid);
 +      parm_data->start = lkoffset;
 +      parm_data->length = len;  /* normalize negative numbers */
 +
 +      pSMB->DataOffset = cpu_to_le16(offset);
 +      pSMB->Fid = smb_file_id;
 +      pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
 +      pSMB->Reserved4 = 0;
 +      pSMB->hdr.smb_buf_length += byte_count;
 +      pSMB->ByteCount = cpu_to_le16(byte_count);
 +      rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
 +                      (struct smb_hdr *) pSMBr, &bytes_returned, 0);
 +      if (rc) {
 +              cFYI(1, ("Send error in Posix Lock = %d", rc));
 +      }
 +
 +      if (pSMB)
 +              cifs_small_buf_release(pSMB);
 +
 +      /* Note: On -EAGAIN error only caller can retry on handle based calls
 +         since file handle passed in no longer valid */
 +
 +      return rc;
 +}
 +
 +
  int
  CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
  {
@@@ -2685,7 -2578,7 +2685,7 @@@ qsec_out
                cifs_small_buf_release(iov[0].iov_base);
        else if(buf_type == CIFS_LARGE_BUFFER)
                cifs_buf_release(iov[0].iov_base);
 -      cifs_small_buf_release(pSMB);
 +/*    cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
        return rc;
  }
  
@@@ -3061,8 -2954,7 +3061,8 @@@ findFirstRetry
        pSMB->TotalParameterCount = cpu_to_le16(params);
        pSMB->ParameterCount = pSMB->TotalParameterCount;
        pSMB->ParameterOffset = cpu_to_le16(
 -        offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes) - 4);
 +            offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
 +              - 4);
        pSMB->DataCount = 0;
        pSMB->DataOffset = 0;
        pSMB->SetupCount = 1;   /* one byte, no need to make endian neutral */
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        cifs_stats_inc(&tcon->num_ffirst);
  
 -      if (rc) {/* BB add logic to retry regular search if Unix search rejected unexpectedly by server */
 +      if (rc) {/* BB add logic to retry regular search if Unix search
 +                      rejected unexpectedly by server */
                /* BB Add code to handle unsupported level rc */
                cFYI(1, ("Error in FindFirst = %d", rc));
  
 -              if (pSMB)
 -                      cifs_buf_release(pSMB);
 +              cifs_buf_release(pSMB);
  
                /* BB eventually could optimize out free and realloc of buf */
                /*    for this case */
                                psrch_inf->unicode = FALSE;
  
                        psrch_inf->ntwrk_buf_start = (char *)pSMBr;
 +                      psrch_inf->smallBuf = 0;
                        psrch_inf->srch_entries_start = 
                                (char *) &pSMBr->hdr.Protocol + 
                                        le16_to_cpu(pSMBr->t2.DataOffset);
@@@ -3227,14 -3118,9 +3227,14 @@@ int CIFSFindNext(const int xid, struct 
                        parms = (T2_FNEXT_RSP_PARMS *)response_data;
                        response_data = (char *)&pSMBr->hdr.Protocol +
                                le16_to_cpu(pSMBr->t2.DataOffset);
 -                      cifs_buf_release(psrch_inf->ntwrk_buf_start);
 +                      if(psrch_inf->smallBuf)
 +                              cifs_small_buf_release(
 +                                      psrch_inf->ntwrk_buf_start);
 +                      else
 +                              cifs_buf_release(psrch_inf->ntwrk_buf_start);
                        psrch_inf->srch_entries_start = response_data;
                        psrch_inf->ntwrk_buf_start = (char *)pSMB;
 +                      psrch_inf->smallBuf = 0;
                        if(parms->EndofSearch)
                                psrch_inf->endOfSearch = TRUE;
                        else
@@@ -3948,7 -3834,6 +3948,7 @@@ CIFSSMBSetFSUnixInfo(const int xid, str
  
        cFYI(1, ("In SETFSUnixInfo"));
  SETFSUnixRetry:
 +      /* BB switch to small buf init to save memory */
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
        if (rc)
@@@ -5023,7 -4908,7 +5023,7 @@@ SetEARetry
        parm_data->list_len = cpu_to_le32(count);
        parm_data->list[0].EA_flags = 0;
        /* we checked above that name len is less than 255 */
-       parm_data->list[0].name_len = (__u8)name_len;;
+       parm_data->list[0].name_len = (__u8)name_len;
        /* EA names are always ASCII */
        if(ea_name)
                strncpy(parm_data->list[0].name,ea_name,name_len);
diff --combined fs/cifs/dir.c
index ddd11fa1552804061b6459297ca274b122acc87a,632561dd9c5004d0bdf68e987d068e69e2a520e0..1d0ca3eaaca51f282bcec21163493fda104b5cad
@@@ -48,14 -48,13 +48,14 @@@ build_path_from_dentry(struct dentry *d
        struct dentry *temp;
        int namelen = 0;
        char *full_path;
 -      char dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb));
 +      char dirsep;
  
        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 */
  
 +      dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb));
  cifs_bp_rename_retry:
        for (temp = direntry; !IS_ROOT(temp);) {
                namelen += (1 + temp->d_name.len);
@@@ -139,9 -138,9 +139,9 @@@ cifs_create(struct inode *inode, struc
        cifs_sb = CIFS_SB(inode->i_sb);
        pTcon = cifs_sb->tcon;
  
-       down(&direntry->d_sb->s_vfs_rename_sem);
+       mutex_lock(&direntry->d_sb->s_vfs_rename_mutex);
        full_path = build_path_from_dentry(direntry);
-       up(&direntry->d_sb->s_vfs_rename_sem);
+       mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex);
        if(full_path == NULL) {
                FreeXid(xid);
                return -ENOMEM;
                        CIFSSMBClose(xid, pTcon, fileHandle);
                } else if(newinode) {
                        pCifsFile =
 -                         kmalloc(sizeof (struct cifsFileInfo), GFP_KERNEL);
 +                         kzalloc(sizeof (struct cifsFileInfo), GFP_KERNEL);
                        
                        if(pCifsFile == NULL)
                                goto cifs_create_out;
 -                      memset((char *)pCifsFile, 0,
 -                             sizeof (struct cifsFileInfo));
                        pCifsFile->netfid = fileHandle;
                        pCifsFile->pid = current->tgid;
                        pCifsFile->pInode = newinode;
@@@ -316,9 -317,9 +316,9 @@@ int cifs_mknod(struct inode *inode, str
        cifs_sb = CIFS_SB(inode->i_sb);
        pTcon = cifs_sb->tcon;
  
-       down(&direntry->d_sb->s_vfs_rename_sem);
+       mutex_lock(&direntry->d_sb->s_vfs_rename_mutex);
        full_path = build_path_from_dentry(direntry);
-       up(&direntry->d_sb->s_vfs_rename_sem);
+       mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex);
        if(full_path == NULL)
                rc = -ENOMEM;
        else if (pTcon->ses->capabilities & CAP_UNIX) {
diff --combined fs/cifs/file.c
index 2c093de26225569b673037769b08cf6f90fe275b,fb49aef1f2ecd9ca3a90d961bcf175e5d5e1f928..5c497c529772a43396a567b515f3927fbe6a1437
@@@ -203,9 -203,9 +203,9 @@@ int cifs_open(struct inode *inode, stru
                }
        }
  
-       down(&inode->i_sb->s_vfs_rename_sem);
+       mutex_lock(&inode->i_sb->s_vfs_rename_mutex);
        full_path = build_path_from_dentry(file->f_dentry);
-       up(&inode->i_sb->s_vfs_rename_sem);
+       mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);
        if (full_path == NULL) {
                FreeXid(xid);
                return -ENOMEM;
@@@ -555,10 -555,7 +555,10 @@@ int cifs_closedir(struct inode *inode, 
                if (ptmp) {
                        cFYI(1, ("closedir free smb buf in srch struct"));
                        pCFileStruct->srch_inf.ntwrk_buf_start = NULL;
 -                      cifs_buf_release(ptmp);
 +                      if(pCFileStruct->srch_inf.smallBuf)
 +                              cifs_small_buf_release(ptmp);
 +                      else
 +                              cifs_buf_release(ptmp);
                }
                ptmp = pCFileStruct->search_resume_name;
                if (ptmp) {
  int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
  {
        int rc, xid;
 -      __u32 lockType = LOCKING_ANDX_LARGE_FILES;
        __u32 numLock = 0;
        __u32 numUnlock = 0;
        __u64 length;
        int wait_flag = FALSE;
        struct cifs_sb_info *cifs_sb;
        struct cifsTconInfo *pTcon;
 +      __u16 netfid;
 +      __u8 lockType = LOCKING_ANDX_LARGE_FILES;
  
        length = 1 + pfLock->fl_end - pfLock->fl_start;
        rc = -EACCES;
                pfLock->fl_end));
  
        if (pfLock->fl_flags & FL_POSIX)
 -              cFYI(1, ("Posix "));
 +              cFYI(1, ("Posix"));
        if (pfLock->fl_flags & FL_FLOCK)
 -              cFYI(1, ("Flock "));
 +              cFYI(1, ("Flock"));
        if (pfLock->fl_flags & FL_SLEEP) {
 -              cFYI(1, ("Blocking lock "));
 +              cFYI(1, ("Blocking lock"));
                wait_flag = TRUE;
        }
        if (pfLock->fl_flags & FL_ACCESS)
                cFYI(1, ("F_WRLCK "));
                numLock = 1;
        } else if (pfLock->fl_type == F_UNLCK) {
 -              cFYI(1, ("F_UNLCK "));
 +              cFYI(1, ("F_UNLCK"));
                numUnlock = 1;
 +              /* Check if unlock includes more than
 +              one lock range */
        } else if (pfLock->fl_type == F_RDLCK) {
 -              cFYI(1, ("F_RDLCK "));
 +              cFYI(1, ("F_RDLCK"));
                lockType |= LOCKING_ANDX_SHARED_LOCK;
                numLock = 1;
        } else if (pfLock->fl_type == F_EXLCK) {
 -              cFYI(1, ("F_EXLCK "));
 +              cFYI(1, ("F_EXLCK"));
                numLock = 1;
        } else if (pfLock->fl_type == F_SHLCK) {
 -              cFYI(1, ("F_SHLCK "));
 +              cFYI(1, ("F_SHLCK"));
                lockType |= LOCKING_ANDX_SHARED_LOCK;
                numLock = 1;
        } else
 -              cFYI(1, ("Unknown type of lock "));
 +              cFYI(1, ("Unknown type of lock"));
  
        cifs_sb = CIFS_SB(file->f_dentry->d_sb);
        pTcon = cifs_sb->tcon;
                FreeXid(xid);
                return -EBADF;
        }
 +      netfid = ((struct cifsFileInfo *)file->private_data)->netfid;
 +
  
 +      /* BB add code here to normalize offset and length to
 +      account for negative length which we can not accept over the
 +      wire */
        if (IS_GETLK(cmd)) {
 -              rc = CIFSSMBLock(xid, pTcon,
 -                               ((struct cifsFileInfo *)file->
 -                                private_data)->netfid,
 -                               length,
 -                               pfLock->fl_start, 0, 1, lockType,
 -                               0 /* wait flag */ );
 +              if(experimEnabled && 
 +                 (cifs_sb->tcon->ses->capabilities & CAP_UNIX) &&
 +                 (CIFS_UNIX_FCNTL_CAP & 
 +                      le64_to_cpu(cifs_sb->tcon->fsUnixInfo.Capability))) {
 +                      int posix_lock_type;
 +                      if(lockType & LOCKING_ANDX_SHARED_LOCK)
 +                              posix_lock_type = CIFS_RDLCK;
 +                      else
 +                              posix_lock_type = CIFS_WRLCK;
 +                      rc = CIFSSMBPosixLock(xid, pTcon, netfid, 1 /* get */,
 +                                      length, pfLock->fl_start,
 +                                      posix_lock_type, wait_flag);
 +                      FreeXid(xid);
 +                      return rc;
 +              }
 +
 +              /* BB we could chain these into one lock request BB */
 +              rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start,
 +                               0, 1, lockType, 0 /* wait flag */ );
                if (rc == 0) {
 -                      rc = CIFSSMBLock(xid, pTcon,
 -                                       ((struct cifsFileInfo *) file->
 -                                        private_data)->netfid,
 -                                       length,
 +                      rc = CIFSSMBLock(xid, pTcon, netfid, length, 
                                         pfLock->fl_start, 1 /* numUnlock */ ,
                                         0 /* numLock */ , lockType,
                                         0 /* wait flag */ );
                        pfLock->fl_type = F_UNLCK;
                        if (rc != 0)
                                cERROR(1, ("Error unlocking previously locked "
 -                                         "range %d during test of lock ",
 -                                         rc));
 +                                         "range %d during test of lock", rc));
                        rc = 0;
  
                } else {
                FreeXid(xid);
                return rc;
        }
 -
 -      rc = CIFSSMBLock(xid, pTcon,
 -                       ((struct cifsFileInfo *) file->private_data)->
 -                       netfid, length,
 -                       pfLock->fl_start, numUnlock, numLock, lockType,
 -                       wait_flag);
 +      if (experimEnabled &&
 +              (cifs_sb->tcon->ses->capabilities & CAP_UNIX) &&
 +              (CIFS_UNIX_FCNTL_CAP &
 +                       le64_to_cpu(cifs_sb->tcon->fsUnixInfo.Capability))) {
 +              int posix_lock_type;
 +              if(lockType & LOCKING_ANDX_SHARED_LOCK)
 +                      posix_lock_type = CIFS_RDLCK;
 +              else
 +                      posix_lock_type = CIFS_WRLCK;
 +              
 +              if(numUnlock == 1)
 +                      posix_lock_type = CIFS_UNLCK;
 +              else if(numLock == 0) {
 +                      /* if no lock or unlock then nothing
 +                      to do since we do not know what it is */
 +                      FreeXid(xid);
 +                      return -EOPNOTSUPP;
 +              }
 +              rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */,
 +                                    length, pfLock->fl_start,
 +                                    posix_lock_type, wait_flag);
 +      } else
 +              rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start,
 +                              numUnlock, numLock, lockType, wait_flag);
        if (pfLock->fl_flags & FL_POSIX)
                posix_lock_file_wait(file, pfLock);
        FreeXid(xid);
@@@ -1377,7 -1339,7 +1377,7 @@@ int cifs_fsync(struct file *file, struc
        return rc;
  }
  
- /* static int cifs_sync_page(struct page *page)
+ /* static void cifs_sync_page(struct page *page)
  {
        struct address_space *mapping;
        struct inode *inode;
                return 0;
        inode = mapping->host;
        if (!inode)
-               return 0; */
+               return; */
  
  /*    fill in rpages then 
        result = cifs_pagein_inode(inode, index, rpages); */ /* BB finish */
  
  /*    cFYI(1, ("rpages is %d for sync page of Index %ld ", rpages, index));
  
+ #if 0
        if (rc < 0)
                return rc;
        return 0;
+ #endif
  } */
  
  /*
diff --combined fs/cifs/inode.c
index b21038b99fc27c6859ab165f5df7645fd5a6d453,598eec9778f67cbba3c0feb29d01c7b6c9e0f9d5..e842ce9f65476c7c08037af4217b319635533eee
@@@ -163,9 -163,9 +163,9 @@@ int cifs_get_inode_info_unix(struct ino
  
                if (num_of_bytes < end_of_file)
                        cFYI(1, ("allocation size less than end of file"));
-               cFYI(1,
-                    ("Size %ld and blocks %ld",
-                     (unsigned long) inode->i_size, inode->i_blocks));
+               cFYI(1, ("Size %ld and blocks %llu",
+                       (unsigned long) inode->i_size,
+                       (unsigned long long)inode->i_blocks));
                if (S_ISREG(inode->i_mode)) {
                        cFYI(1, ("File inode"));
                        inode->i_op = &cifs_file_inode_ops;
@@@ -574,9 -574,9 +574,9 @@@ int cifs_unlink(struct inode *inode, st
  
        /* Unlink can be called from rename so we can not grab the sem here
           since we deadlock otherwise */
- /*    down(&direntry->d_sb->s_vfs_rename_sem);*/
+ /*    mutex_lock(&direntry->d_sb->s_vfs_rename_mutex);*/
        full_path = build_path_from_dentry(direntry);
- /*    up(&direntry->d_sb->s_vfs_rename_sem);*/
+ /*    mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex);*/
        if (full_path == NULL) {
                FreeXid(xid);
                return -ENOMEM;
                }
        } else if (rc == -EACCES) {
                /* try only if r/o attribute set in local lookup data? */
 -              pinfo_buf = kmalloc(sizeof(FILE_BASIC_INFO), GFP_KERNEL);
 +              pinfo_buf = kzalloc(sizeof(FILE_BASIC_INFO), GFP_KERNEL);
                if (pinfo_buf) {
 -                      memset(pinfo_buf, 0, sizeof(FILE_BASIC_INFO));
                        /* ATTRS set to normal clears r/o bit */
                        pinfo_buf->Attributes = cpu_to_le32(ATTR_NORMAL);
                        if (!(pTcon->ses->flags & CIFS_SES_NT4))
@@@ -717,9 -718,9 +717,9 @@@ int cifs_mkdir(struct inode *inode, str
        cifs_sb = CIFS_SB(inode->i_sb);
        pTcon = cifs_sb->tcon;
  
-       down(&inode->i_sb->s_vfs_rename_sem);
+       mutex_lock(&inode->i_sb->s_vfs_rename_mutex);
        full_path = build_path_from_dentry(direntry);
-       up(&inode->i_sb->s_vfs_rename_sem);
+       mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);
        if (full_path == NULL) {
                FreeXid(xid);
                return -ENOMEM;
@@@ -802,9 -803,9 +802,9 @@@ int cifs_rmdir(struct inode *inode, str
        cifs_sb = CIFS_SB(inode->i_sb);
        pTcon = cifs_sb->tcon;
  
-       down(&inode->i_sb->s_vfs_rename_sem);
+       mutex_lock(&inode->i_sb->s_vfs_rename_mutex);
        full_path = build_path_from_dentry(direntry);
-       up(&inode->i_sb->s_vfs_rename_sem);
+       mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);
        if (full_path == NULL) {
                FreeXid(xid);
                return -ENOMEM;
@@@ -1136,9 -1137,9 +1136,9 @@@ int cifs_setattr(struct dentry *direntr
                        rc = 0;
        }
                
-       down(&direntry->d_sb->s_vfs_rename_sem);
+       mutex_lock(&direntry->d_sb->s_vfs_rename_mutex);
        full_path = build_path_from_dentry(direntry);
-       up(&direntry->d_sb->s_vfs_rename_sem);
+       mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex);
        if (full_path == NULL) {
                FreeXid(xid);
                return -ENOMEM;
                                                nfid, npid, FALSE);
                        atomic_dec(&open_file->wrtPending);
                        cFYI(1,("SetFSize for attrs rc = %d", rc));
 -                      if(rc == -EINVAL) {
 +                      if((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
                                int bytes_written;
                                rc = CIFSSMBWrite(xid, pTcon,
                                                  nfid, 0, attrs->ia_size,
                                           cifs_sb->mnt_cifs_flags &
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
                        cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc));
 -                      if(rc == -EINVAL) {
 +                      if((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
                                __u16 netfid;
                                int oplock = FALSE;
  
diff --combined fs/cifs/link.c
index ce86ec69fe01c2dc4fe47965c84f0e7e8e74ac7f,8d0da7c87c7b6f0c0025df01b408c673204bc744..9562f5bba65c14e3eb4e42beb1b2a7bf8f498a42
@@@ -48,10 -48,10 +48,10 @@@ cifs_hardlink(struct dentry *old_file, 
  /* 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) */
  
-       down(&inode->i_sb->s_vfs_rename_sem);
+       mutex_lock(&inode->i_sb->s_vfs_rename_mutex);
        fromName = build_path_from_dentry(old_file);
        toName = build_path_from_dentry(direntry);
-       up(&inode->i_sb->s_vfs_rename_sem);
+       mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);
        if((fromName == NULL) || (toName == NULL)) {
                rc = -ENOMEM;
                goto cifs_hl_exit;
@@@ -67,7 -67,7 +67,7 @@@
                                        cifs_sb_target->local_nls, 
                                        cifs_sb_target->mnt_cifs_flags &
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
 -              if(rc == -EIO)
 +              if((rc == -EIO) || (rc == -EINVAL))
                        rc = -EOPNOTSUPP;  
        }
  
@@@ -103,9 -103,9 +103,9 @@@ cifs_follow_link(struct dentry *direntr
  
        xid = GetXid();
  
-       down(&direntry->d_sb->s_vfs_rename_sem);
+       mutex_lock(&direntry->d_sb->s_vfs_rename_mutex);
        full_path = build_path_from_dentry(direntry);
-       up(&direntry->d_sb->s_vfs_rename_sem);
+       mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex);
  
        if (!full_path)
                goto out_no_free;
@@@ -164,9 -164,9 +164,9 @@@ cifs_symlink(struct inode *inode, struc
        cifs_sb = CIFS_SB(inode->i_sb);
        pTcon = cifs_sb->tcon;
  
-       down(&inode->i_sb->s_vfs_rename_sem);
+       mutex_lock(&inode->i_sb->s_vfs_rename_mutex);
        full_path = build_path_from_dentry(direntry);
-       up(&inode->i_sb->s_vfs_rename_sem);
+       mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);
  
        if(full_path == NULL) {
                FreeXid(xid);
@@@ -232,9 -232,9 +232,9 @@@ cifs_readlink(struct dentry *direntry, 
  
  /* BB would it be safe against deadlock to grab this sem 
        even though rename itself grabs the sem and calls lookup? */
- /*       down(&inode->i_sb->s_vfs_rename_sem);*/
+ /*       mutex_lock(&inode->i_sb->s_vfs_rename_mutex);*/
        full_path = build_path_from_dentry(direntry);
- /*       up(&inode->i_sb->s_vfs_rename_sem);*/
+ /*       mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);*/
  
        if(full_path == NULL) {
                FreeXid(xid);
diff --combined fs/cifs/readdir.c
index 405d4b7ec3acb25e1b7ee34824cc4520e2667902,488bd0d81dcf8dc0a47b680a431b9155db06de6f..2f6e2825571ec22f630f77981d3fe9a174418a2c
@@@ -197,10 -197,10 +197,10 @@@ static void fill_in_inode(struct inode 
  
        if (allocation_size < end_of_file)
                cFYI(1, ("May be sparse file, allocation less than file size"));
-       cFYI(1,
-            ("File Size %ld and blocks %ld and blocksize %ld",
-             (unsigned long)tmp_inode->i_size, tmp_inode->i_blocks,
-             tmp_inode->i_blksize));
+       cFYI(1, ("File Size %ld and blocks %llu and blocksize %ld",
+               (unsigned long)tmp_inode->i_size,
+               (unsigned long long)tmp_inode->i_blocks,
+               tmp_inode->i_blksize));
        if (S_ISREG(tmp_inode->i_mode)) {
                cFYI(1, ("File inode"));
                tmp_inode->i_op = &cifs_file_inode_ops;
@@@ -404,9 -404,9 +404,9 @@@ static int initiate_cifs_search(const i
        if(pTcon == NULL)
                return -EINVAL;
  
-       down(&file->f_dentry->d_sb->s_vfs_rename_sem);
+       mutex_lock(&file->f_dentry->d_sb->s_vfs_rename_mutex);
        full_path = build_path_from_dentry(file->f_dentry);
-       up(&file->f_dentry->d_sb->s_vfs_rename_sem);
+       mutex_unlock(&file->f_dentry->d_sb->s_vfs_rename_mutex);
  
        if(full_path == NULL) {
                return -ENOMEM;
@@@ -604,12 -604,7 +604,12 @@@ static int find_cifs_entry(const int xi
                cifsFile->search_resume_name = NULL;
                if(cifsFile->srch_inf.ntwrk_buf_start) {
                        cFYI(1,("freeing SMB ff cache buf on search rewind"));
 -                      cifs_buf_release(cifsFile->srch_inf.ntwrk_buf_start);
 +                      if(cifsFile->srch_inf.smallBuf)
 +                              cifs_small_buf_release(cifsFile->srch_inf.
 +                                              ntwrk_buf_start);
 +                      else
 +                              cifs_buf_release(cifsFile->srch_inf.
 +                                              ntwrk_buf_start);
                }
                rc = initiate_cifs_search(xid,file);
                if(rc) {