]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
Merge branch 'for-next' of git://git.samba.org/sfrench/cifs-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 10 Jun 2014 02:08:43 +0000 (19:08 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 10 Jun 2014 02:08:43 +0000 (19:08 -0700)
Pull CIFS fixes from Steve French.

* 'for-next' of git://git.samba.org/sfrench/cifs-2.6:
  CIFS: Fix memory leaks in SMB2_open
  cifs: ensure that vol->username is not NULL before running strlen on it
  Clarify SMB2/SMB3 create context and add missing ones
  Do not send ClientGUID on SMB2.02 dialect
  cifs: Set client guid on per connection basis
  fs/cifs/netmisc.c: convert printk to pr_foo()
  fs/cifs/cifs.c: replace seq_printf by seq_puts
  Update cifs version number to 2.03
  fs: cifs: new helper: file_inode(file)
  cifs: fix potential races in cifs_revalidate_mapping
  cifs: new helper function: cifs_revalidate_mapping
  cifs: convert booleans in cifsInodeInfo to a flags field
  cifs: fix cifs_uniqueid_to_ino_t not to ever return 0

1  2 
fs/cifs/inode.c

diff --combined fs/cifs/inode.c
index a22d667f1069e5eb8485d121f241725de732b8a9,9ff8df8b4d84afdabaef66a456ce427ea9a635c5..a174605f6afa56cb73a99335cc966f745a9ded6b
@@@ -22,6 -22,7 +22,7 @@@
  #include <linux/stat.h>
  #include <linux/slab.h>
  #include <linux/pagemap.h>
+ #include <linux/freezer.h>
  #include <asm/div64.h>
  #include "cifsfs.h"
  #include "cifspdu.h"
@@@ -117,7 -118,7 +118,7 @@@ cifs_revalidate_cache(struct inode *ino
  
        cifs_dbg(FYI, "%s: invalidating inode %llu mapping\n",
                 __func__, cifs_i->uniqueid);
-       cifs_i->invalid_mapping = true;
+       set_bit(CIFS_INO_INVALID_MAPPING, &cifs_i->flags);
  }
  
  /*
@@@ -177,7 -178,10 +178,10 @@@ cifs_fattr_to_inode(struct inode *inode
        else
                cifs_i->time = jiffies;
  
-       cifs_i->delete_pending = fattr->cf_flags & CIFS_FATTR_DELETE_PENDING;
+       if (fattr->cf_flags & CIFS_FATTR_DELETE_PENDING)
+               set_bit(CIFS_INO_DELETE_PENDING, &cifs_i->flags);
+       else
+               clear_bit(CIFS_INO_DELETE_PENDING, &cifs_i->flags);
  
        cifs_i->server_eof = fattr->cf_eof;
        /*
@@@ -1121,7 -1125,7 +1125,7 @@@ cifs_rename_pending_delete(const char *
        }
  
        /* try to set DELETE_ON_CLOSE */
-       if (!cifsInode->delete_pending) {
+       if (!test_bit(CIFS_INO_DELETE_PENDING, &cifsInode->flags)) {
                rc = CIFSSMBSetFileDisposition(xid, tcon, true, fid.netfid,
                                               current->tgid);
                /*
                        rc = -EBUSY;
                        goto undo_rename;
                }
-               cifsInode->delete_pending = true;
+               set_bit(CIFS_INO_DELETE_PENDING, &cifsInode->flags);
        }
  
  out_close:
  cifs_invalidate_mapping(struct inode *inode)
  {
        int rc = 0;
-       struct cifsInodeInfo *cifs_i = CIFS_I(inode);
-       cifs_i->invalid_mapping = false;
  
        if (inode->i_mapping && inode->i_mapping->nrpages != 0) {
                rc = invalidate_inode_pages2(inode->i_mapping);
-               if (rc) {
+               if (rc)
                        cifs_dbg(VFS, "%s: could not invalidate inode %p\n",
                                 __func__, inode);
-                       cifs_i->invalid_mapping = true;
-               }
        }
  
        cifs_fscache_reset_inode_cookie(inode);
        return rc;
  }
  
 -      smp_mb__after_clear_bit();
+ /**
+  * cifs_wait_bit_killable - helper for functions that are sleeping on bit locks
+  * @word: long word containing the bit lock
+  */
+ static int
+ cifs_wait_bit_killable(void *word)
+ {
+       if (fatal_signal_pending(current))
+               return -ERESTARTSYS;
+       freezable_schedule_unsafe();
+       return 0;
+ }
+ int
+ cifs_revalidate_mapping(struct inode *inode)
+ {
+       int rc;
+       unsigned long *flags = &CIFS_I(inode)->flags;
+       rc = wait_on_bit_lock(flags, CIFS_INO_LOCK, cifs_wait_bit_killable,
+                               TASK_KILLABLE);
+       if (rc)
+               return rc;
+       if (test_and_clear_bit(CIFS_INO_INVALID_MAPPING, flags)) {
+               rc = cifs_invalidate_mapping(inode);
+               if (rc)
+                       set_bit(CIFS_INO_INVALID_MAPPING, flags);
+       }
+       clear_bit_unlock(CIFS_INO_LOCK, flags);
++      smp_mb__after_atomic();
+       wake_up_bit(flags, CIFS_INO_LOCK);
+       return rc;
+ }
+ int
+ cifs_zap_mapping(struct inode *inode)
+ {
+       set_bit(CIFS_INO_INVALID_MAPPING, &CIFS_I(inode)->flags);
+       return cifs_revalidate_mapping(inode);
+ }
  int cifs_revalidate_file_attr(struct file *filp)
  {
        int rc = 0;
@@@ -1842,9 -1885,7 +1885,7 @@@ int cifs_revalidate_file(struct file *f
        if (rc)
                return rc;
  
-       if (CIFS_I(inode)->invalid_mapping)
-               rc = cifs_invalidate_mapping(inode);
-       return rc;
+       return cifs_revalidate_mapping(inode);
  }
  
  /* revalidate a dentry's inode attributes */
@@@ -1857,9 -1898,7 +1898,7 @@@ int cifs_revalidate_dentry(struct dentr
        if (rc)
                return rc;
  
-       if (CIFS_I(inode)->invalid_mapping)
-               rc = cifs_invalidate_mapping(inode);
-       return rc;
+       return cifs_revalidate_mapping(inode);
  }
  
  int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,