Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
authorSteve French <sfrench@us.ibm.com>
Thu, 12 Jan 2006 22:47:08 +0000 (14:47 -0800)
committerSteve French <sfrench@us.ibm.com>
Thu, 12 Jan 2006 22:47:08 +0000 (14:47 -0800)
Signed-off-by: Steve French <sfrench@us.ibm.com>
1  2 
fs/cifs/cifsfs.c
fs/cifs/file.c
fs/cifs/inode.c

diff --combined fs/cifs/cifsfs.c
index 136af8a08f45b87d7ad4f87511d5f13095ba4715,e10213b7541e4ec6685daa2c91ffe6a8aaf2c1c4..79eeccd0437f08c2a3ac56a51af2de0cadc36f19
@@@ -513,17 -513,6 +513,17 @@@ static ssize_t cifs_file_aio_write(stru
        return written;
  }
  
 +static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
 +{
 +      /* origin == SEEK_END => we must revalidate the cached file length */
 +      if (origin == 2) {
 +              int retval = cifs_revalidate(file->f_dentry);
 +              if (retval < 0)
 +                      return (loff_t)retval;
 +      }
 +      return remote_llseek(file, offset, origin);
 +}
 +
  static struct file_system_type cifs_fs_type = {
        .owner = THIS_MODULE,
        .name = "cifs",
@@@ -597,7 -586,6 +597,7 @@@ struct file_operations cifs_file_ops = 
        .flush = cifs_flush,
        .mmap  = cifs_file_mmap,
        .sendfile = generic_file_sendfile,
 +      .llseek = cifs_llseek,
  #ifdef CONFIG_CIFS_POSIX
        .ioctl  = cifs_ioctl,
  #endif /* CONFIG_CIFS_POSIX */
@@@ -621,7 -609,7 +621,7 @@@ struct file_operations cifs_file_direct
  #ifdef CONFIG_CIFS_POSIX
        .ioctl  = cifs_ioctl,
  #endif /* CONFIG_CIFS_POSIX */
 -
 +      .llseek = cifs_llseek,
  #ifdef CONFIG_CIFS_EXPERIMENTAL
        .dir_notify = cifs_dir_notify,
  #endif /* CONFIG_CIFS_EXPERIMENTAL */
@@@ -639,7 -627,6 +639,7 @@@ struct file_operations cifs_file_nobrl_
        .flush = cifs_flush,
        .mmap  = cifs_file_mmap,
        .sendfile = generic_file_sendfile,
 +      .llseek = cifs_llseek,
  #ifdef CONFIG_CIFS_POSIX
        .ioctl  = cifs_ioctl,
  #endif /* CONFIG_CIFS_POSIX */
@@@ -662,7 -649,7 +662,7 @@@ struct file_operations cifs_file_direct
  #ifdef CONFIG_CIFS_POSIX
        .ioctl  = cifs_ioctl,
  #endif /* CONFIG_CIFS_POSIX */
 -
 +      .llseek = cifs_llseek,
  #ifdef CONFIG_CIFS_EXPERIMENTAL
        .dir_notify = cifs_dir_notify,
  #endif /* CONFIG_CIFS_EXPERIMENTAL */
@@@ -746,7 -733,7 +746,7 @@@ cifs_init_request_bufs(void
                kmem_cache_destroy(cifs_req_cachep);
                return -ENOMEM;
        }
 -      /* 256 (MAX_CIFS_HDR_SIZE bytes is enough for most SMB responses and
 +      /* MAX_CIFS_SMALL_BUFFER_SIZE bytes is enough for most SMB responses and
        almost all handle based requests (but not write response, nor is it
        sufficient for path based requests).  A smaller size would have
        been more efficient (compacting multiple slab items on one 4k page) 
        efficient to alloc 1 per page off the slab compared to 17K (5page) 
        alloc of large cifs buffers even when page debugging is on */
        cifs_sm_req_cachep = kmem_cache_create("cifs_small_rq",
 -                      MAX_CIFS_HDR_SIZE, 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
 +                      MAX_CIFS_SMALL_BUFFER_SIZE, 0, SLAB_HWCACHE_ALIGN, 
 +                      NULL, NULL);
        if (cifs_sm_req_cachep == NULL) {
                mempool_destroy(cifs_req_poolp);
                kmem_cache_destroy(cifs_req_cachep);
@@@ -874,9 -860,9 +874,9 @@@ static int cifs_oplock_thread(void * du
                                DeleteOplockQEntry(oplock_item);
                                /* can not grab inode sem here since it would
                                deadlock when oplock received on delete 
-                               since vfs_unlink holds the i_sem across
+                               since vfs_unlink holds the i_mutex across
                                the call */
-                               /* down(&inode->i_sem);*/
+                               /* mutex_lock(&inode->i_mutex);*/
                                if (S_ISREG(inode->i_mode)) {
                                        rc = filemap_fdatawrite(inode->i_mapping);
                                        if(CIFS_I(inode)->clientCanCacheRead == 0) {
                                        }
                                } else
                                        rc = 0;
-                               /* up(&inode->i_sem);*/
+                               /* mutex_unlock(&inode->i_mutex);*/
                                if (rc)
                                        CIFS_I(inode)->write_behind_rc = rc;
                                cFYI(1,("Oplock flush inode %p rc %d",inode,rc));
@@@ -968,12 -954,6 +968,12 @@@ init_cifs(void
        atomic_set(&tconInfoReconnectCount, 0);
  
        atomic_set(&bufAllocCount, 0);
 +      atomic_set(&smBufAllocCount, 0);
 +#ifdef CONFIG_CIFS_STATS2
 +      atomic_set(&totBufAllocCount, 0);
 +      atomic_set(&totSmBufAllocCount, 0);
 +#endif /* CONFIG_CIFS_STATS2 */
 +
        atomic_set(&midCount, 0);
        GlobalCurrentXid = 0;
        GlobalTotalActiveXid = 0;
diff --combined fs/cifs/file.c
index 670ec1e84da081b668a0f1a712ed30c9192da21d,5ade53d7bca89624cd6b9381d4e6ba91543517be..378095a442d0a5ba325ee7ac118b50d4f9fdebf6
@@@ -127,8 -127,7 +127,7 @@@ static inline int cifs_open_inode_helpe
                if (file->f_dentry->d_inode->i_mapping) {
                /* BB no need to lock inode until after invalidate
                   since namei code should already have it locked? */
-                       filemap_fdatawrite(file->f_dentry->d_inode->i_mapping);
-                       filemap_fdatawait(file->f_dentry->d_inode->i_mapping);
+                       filemap_write_and_wait(file->f_dentry->d_inode->i_mapping);
                }
                cFYI(1, ("invalidating remote inode since open detected it "
                         "changed"));
@@@ -419,8 -418,7 +418,7 @@@ static int cifs_reopen_file(struct inod
                pCifsInode = CIFS_I(inode);
                if (pCifsInode) {
                        if (can_flush) {
-                               filemap_fdatawrite(inode->i_mapping);
-                               filemap_fdatawait(inode->i_mapping);
+                               filemap_write_and_wait(inode->i_mapping);
                        /* temporarily disable caching while we
                           go to server to get inode info */
                                pCifsInode->clientCanCacheAll = FALSE;
@@@ -555,13 -553,13 +553,13 @@@ int cifs_closedir(struct inode *inode, 
                }
                ptmp = pCFileStruct->srch_inf.ntwrk_buf_start;
                if (ptmp) {
 -   /* BB removeme BB */       cFYI(1, ("freeing smb buf in srch struct in closedir"));
 +                      cFYI(1, ("closedir free smb buf in srch struct"));
                        pCFileStruct->srch_inf.ntwrk_buf_start = NULL;
                        cifs_buf_release(ptmp);
                }
                ptmp = pCFileStruct->search_resume_name;
                if (ptmp) {
 -   /* BB removeme BB */       cFYI(1, ("freeing resume name in closedir"));
 +                      cFYI(1, ("closedir free resume name"));
                        pCFileStruct->search_resume_name = NULL;
                        kfree(ptmp);
                }
@@@ -870,9 -868,10 +868,9 @@@ static ssize_t cifs_write(struct file *
                                if (rc != 0)
                                        break;
                        }
 -#ifdef CONFIG_CIFS_EXPERIMENTAL
                        /* BB FIXME We can not sign across two buffers yet */
 -                      if((experimEnabled) && ((pTcon->ses->server->secMode & 
 -                       (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0)) {
 +                      if((pTcon->ses->server->secMode & 
 +                       (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0) {
                                struct kvec iov[2];
                                unsigned int len;
  
                                                iov, 1, long_op);
                        } else
                        /* BB FIXME fixup indentation of line below */
 -#endif                        
                        rc = CIFSSMBWrite(xid, pTcon,
                                 open_file->netfid,
                                 min_t(const int, cifs_sb->wsize, 
@@@ -1024,6 -1024,7 +1022,6 @@@ static int cifs_partialpagewrite(struc
        return rc;
  }
  
 -#ifdef CONFIG_CIFS_EXPERIMENTAL
  static int cifs_writepages(struct address_space *mapping,
                           struct writeback_control *wbc)
  {
@@@ -1226,6 -1227,7 +1224,6 @@@ retry
  
        return rc;
  }
 -#endif
  
  static int cifs_writepage(struct page* page, struct writeback_control *wbc)
  {
@@@ -1424,7 -1426,6 +1422,7 @@@ ssize_t cifs_user_read(struct file *fil
                rc = -EAGAIN;
                smb_read_data = NULL;
                while (rc == -EAGAIN) {
 +                      int buf_type = CIFS_NO_BUFFER;
                        if ((open_file->invalidHandle) && 
                            (!open_file->closePend)) {
                                rc = cifs_reopen_file(file->f_dentry->d_inode,
                                        break;
                        }
                        rc = CIFSSMBRead(xid, pTcon,
 -                                      open_file->netfid,
 -                                      current_read_size, *poffset,
 -                                      &bytes_read, &smb_read_data);
 +                                       open_file->netfid,
 +                                       current_read_size, *poffset,
 +                                       &bytes_read, &smb_read_data,
 +                                       &buf_type);
                        pSMBr = (struct smb_com_read_rsp *)smb_read_data;
                        if (copy_to_user(current_offset, 
                                         smb_read_data + 4 /* RFC1001 hdr */
                                         + le16_to_cpu(pSMBr->DataOffset), 
                                         bytes_read)) {
                                rc = -EFAULT;
 -                              FreeXid(xid);
 -                              return rc;
 -            }
 +                      }
                        if (smb_read_data) {
 -                              cifs_buf_release(smb_read_data);
 +                              if(buf_type == CIFS_SMALL_BUFFER)
 +                                      cifs_small_buf_release(smb_read_data);
 +                              else if(buf_type == CIFS_LARGE_BUFFER)
 +                                      cifs_buf_release(smb_read_data);
                                smb_read_data = NULL;
                        }
                }
@@@ -1481,7 -1480,6 +1479,7 @@@ static ssize_t cifs_read(struct file *f
        int xid;
        char *current_offset;
        struct cifsFileInfo *open_file;
 +      int buf_type = CIFS_NO_BUFFER;
  
        xid = GetXid();
        cifs_sb = CIFS_SB(file->f_dentry->d_sb);
                                        break;
                        }
                        rc = CIFSSMBRead(xid, pTcon,
 -                                      open_file->netfid,
 -                                      current_read_size, *poffset,
 -                                      &bytes_read, &current_offset);
 +                                       open_file->netfid,
 +                                       current_read_size, *poffset,
 +                                       &bytes_read, &current_offset,
 +                                       &buf_type);
                }
                if (rc || (bytes_read == 0)) {
                        if (total_read) {
@@@ -1619,7 -1616,6 +1617,7 @@@ static int cifs_readpages(struct file *
        struct smb_com_read_rsp *pSMBr;
        struct pagevec lru_pvec;
        struct cifsFileInfo *open_file;
 +      int buf_type = CIFS_NO_BUFFER;
  
        xid = GetXid();
        if (file->private_data == NULL) {
                        }
  
                        rc = CIFSSMBRead(xid, pTcon,
 -                                      open_file->netfid,
 -                                      read_size, offset,
 -                                      &bytes_read, &smb_read_data);
 -
 +                                       open_file->netfid,
 +                                       read_size, offset,
 +                                       &bytes_read, &smb_read_data,
 +                                       &buf_type);
                        /* BB more RC checks ? */
                        if (rc== -EAGAIN) {
                                if (smb_read_data) {
 -                                      cifs_buf_release(smb_read_data);
 +                                      if(buf_type == CIFS_SMALL_BUFFER)
 +                                              cifs_small_buf_release(smb_read_data);
 +                                      else if(buf_type == CIFS_LARGE_BUFFER)
 +                                              cifs_buf_release(smb_read_data);
                                        smb_read_data = NULL;
                                }
                        }
                        break;
                }
                if (smb_read_data) {
 -                      cifs_buf_release(smb_read_data);
 +                      if(buf_type == CIFS_SMALL_BUFFER)
 +                              cifs_small_buf_release(smb_read_data);
 +                      else if(buf_type == CIFS_LARGE_BUFFER)
 +                              cifs_buf_release(smb_read_data);
                        smb_read_data = NULL;
                }
                bytes_read = 0;
@@@ -1835,20 -1825,10 +1833,20 @@@ int is_size_safe_to_change(struct cifsI
                open_file =  find_writable_file(cifsInode);
   
        if(open_file) {
 +              struct cifs_sb_info *cifs_sb;
 +
                /* there is not actually a write pending so let
                this handle go free and allow it to
                be closable if needed */
                atomic_dec(&open_file->wrtPending);
 +
 +              cifs_sb = CIFS_SB(cifsInode->vfs_inode.i_sb);
 +              if ( cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO ) {
 +                      /* since no page cache to corrupt on directio 
 +                      we can change size safely */
 +                      return 1;
 +              }
 +
                return 0;
        } else
                return 1;
@@@ -1893,7 -1873,9 +1891,7 @@@ struct address_space_operations cifs_ad
        .readpage = cifs_readpage,
        .readpages = cifs_readpages,
        .writepage = cifs_writepage,
 -#ifdef CONFIG_CIFS_EXPERIMENTAL
        .writepages = cifs_writepages,
 -#endif
        .prepare_write = cifs_prepare_write,
        .commit_write = cifs_commit_write,
        .set_page_dirty = __set_page_dirty_nobuffers,
diff --combined fs/cifs/inode.c
index f65310cc60a187e9384ebcf1b7ac183de641a5b6,3ebce9430f4a9f6af94085f998d4682027d01edc..59359911f4810c601923261c94cd49ffeebf5542
@@@ -229,12 -229,11 +229,12 @@@ static int decode_sfu_inode(struct inod
                         cifs_sb->mnt_cifs_flags &
                                CIFS_MOUNT_MAP_SPECIAL_CHR);
        if (rc==0) {
 +              int buf_type = CIFS_NO_BUFFER;
                        /* Read header */
                rc = CIFSSMBRead(xid, pTcon,
                                 netfid,
                                 24 /* length */, 0 /* offset */,
 -                               &bytes_read, &pbuf);
 +                               &bytes_read, &pbuf, &buf_type);
                if((rc == 0) && (bytes_read >= 8)) {
                        if(memcmp("IntxBLK", pbuf, 8) == 0) {
                                cFYI(1,("Block device"));
                } else {
                        inode->i_mode |= S_IFREG; /* then it is a file */
                        rc = -EOPNOTSUPP; /* or some unknown SFU type */        
 -              }
 +              }               
                CIFSSMBClose(xid, pTcon, netfid);
        }
        return rc;
@@@ -751,8 -750,8 +751,8 @@@ int cifs_mkdir(struct inode *inode, str
                        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
                                CIFSSMBUnixSetPerms(xid, pTcon, full_path,
                                                    mode,
 -                                                  (__u64)current->euid,
 -                                                  (__u64)current->egid,
 +                                                  (__u64)current->fsuid,
 +                                                  (__u64)current->fsgid,
                                                    0 /* dev_t */,
                                                    cifs_sb->local_nls,
                                                    cifs_sb->mnt_cifs_flags &
@@@ -1041,9 -1040,9 +1041,9 @@@ int cifs_revalidate(struct dentry *dire
        }
  
        /* can not grab this sem since kernel filesys locking documentation
-          indicates i_sem may be taken by the kernel on lookup and rename
-          which could deadlock if we grab the i_sem here as well */
- /*    down(&direntry->d_inode->i_sem);*/
+          indicates i_mutex may be taken by the kernel on lookup and rename
+          which could deadlock if we grab the i_mutex here as well */
+ /*    mutex_lock(&direntry->d_inode->i_mutex);*/
        /* need to write out dirty pages here  */
        if (direntry->d_inode->i_mapping) {
                /* do we need to lock inode until after invalidate completes
                        }
                }
        }
- /*    up(&direntry->d_inode->i_sem); */
+ /*    mutex_unlock(&direntry->d_inode->i_mutex); */
        
        kfree(full_path);
        FreeXid(xid);
@@@ -1149,8 -1148,7 +1149,7 @@@ int cifs_setattr(struct dentry *direntr
        /* BB check if we need to refresh inode from server now ? BB */
  
        /* need to flush data before changing file size on server */
-       filemap_fdatawrite(direntry->d_inode->i_mapping);
-       filemap_fdatawait(direntry->d_inode->i_mapping);
+       filemap_write_and_wait(direntry->d_inode->i_mapping);
  
        if (attrs->ia_valid & ATTR_SIZE) {
                /* To avoid spurious oplock breaks from server, in the case of