]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 3 Jul 2013 16:10:19 +0000 (09:10 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 3 Jul 2013 16:10:19 +0000 (09:10 -0700)
Pull second set of VFS changes from Al Viro:
 "Assorted f_pos race fixes, making do_splice_direct() safe to call with
  i_mutex on parent, O_TMPFILE support, Jeff's locks.c series,
  ->d_hash/->d_compare calling conventions changes from Linus, misc
  stuff all over the place."

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (63 commits)
  Document ->tmpfile()
  ext4: ->tmpfile() support
  vfs: export lseek_execute() to modules
  lseek_execute() doesn't need an inode passed to it
  block_dev: switch to fixed_size_llseek()
  cpqphp_sysfs: switch to fixed_size_llseek()
  tile-srom: switch to fixed_size_llseek()
  proc_powerpc: switch to fixed_size_llseek()
  ubi/cdev: switch to fixed_size_llseek()
  pci/proc: switch to fixed_size_llseek()
  isapnp: switch to fixed_size_llseek()
  lpfc: switch to fixed_size_llseek()
  locks: give the blocked_hash its own spinlock
  locks: add a new "lm_owner_key" lock operation
  locks: turn the blocked_list into a hashtable
  locks: convert fl_link to a hlist_node
  locks: avoid taking global lock if possible when waking up blocked waiters
  locks: protect most of the file_lock handling with i_lock
  locks: encapsulate the fl_link list handling
  locks: make "added" in __posix_lock_file a bool
  ...

13 files changed:
1  2 
Documentation/filesystems/Locking
Documentation/filesystems/vfs.txt
drivers/staging/comedi/comedi_fops.c
fs/cifs/file.c
fs/dcache.c
fs/exec.c
fs/ext3/namei.c
fs/ext4/file.c
fs/ext4/namei.c
fs/fuse/file.c
fs/gfs2/file.c
fs/splice.c
include/linux/fs.h

index 9858f337529c1c6edec3444cf0ac145ec331ed07,e95d3131309eda77d37a9265cbb70c4fb147cd0c..fe7afe22538149706eab5727c989d91a8530c387
@@@ -11,10 -11,8 +11,8 @@@ be able to use diff(1)
  prototypes:
        int (*d_revalidate)(struct dentry *, unsigned int);
        int (*d_weak_revalidate)(struct dentry *, unsigned int);
-       int (*d_hash)(const struct dentry *, const struct inode *,
-                       struct qstr *);
-       int (*d_compare)(const struct dentry *, const struct inode *,
-                       const struct dentry *, const struct inode *,
+       int (*d_hash)(const struct dentry *, struct qstr *);
+       int (*d_compare)(const struct dentry *, const struct dentry *,
                        unsigned int, const char *, const struct qstr *);
        int (*d_delete)(struct dentry *);
        void (*d_release)(struct dentry *);
@@@ -66,6 -64,7 +64,7 @@@ prototypes
        int (*atomic_open)(struct inode *, struct dentry *,
                                struct file *, unsigned open_flag,
                                umode_t create_mode, int *opened);
+       int (*tmpfile) (struct inode *, struct dentry *, umode_t);
  
  locking rules:
        all may block
@@@ -93,6 -92,7 +92,7 @@@ removexattr:  ye
  fiemap:               no
  update_time:  no
  atomic_open:  yes
+ tmpfile:      no
  
        Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on
  victim.
@@@ -189,7 -189,7 +189,7 @@@ prototypes
                                loff_t pos, unsigned len, unsigned copied,
                                struct page *page, void *fsdata);
        sector_t (*bmap)(struct address_space *, sector_t);
 -      int (*invalidatepage) (struct page *, unsigned long);
 +      void (*invalidatepage) (struct page *, unsigned int, unsigned int);
        int (*releasepage) (struct page *, int);
        void (*freepage)(struct page *);
        int (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
@@@ -310,8 -310,8 +310,8 @@@ filesystems and by the swapper. The lat
  keep it that way and don't breed new callers.
  
        ->invalidatepage() is called when the filesystem must attempt to drop
 -some or all of the buffers from the page when it is being truncated.  It
 -returns zero on success.  If ->invalidatepage is zero, the kernel uses
 +some or all of the buffers from the page when it is being truncated. It
 +returns zero on success. If ->invalidatepage is zero, the kernel uses
  block_invalidatepage() instead.
  
        ->releasepage() is called when the kernel is about to try to drop the
@@@ -344,25 -344,38 +344,38 @@@ prototypes
  
  
  locking rules:
-                       file_lock_lock  may block
+                       inode->i_lock   may block
  fl_copy_lock:         yes             no
  fl_release_private:   maybe           no
  
  ----------------------- lock_manager_operations ---------------------------
  prototypes:
        int (*lm_compare_owner)(struct file_lock *, struct file_lock *);
+       unsigned long (*lm_owner_key)(struct file_lock *);
        void (*lm_notify)(struct file_lock *);  /* unblock callback */
        int (*lm_grant)(struct file_lock *, struct file_lock *, int);
        void (*lm_break)(struct file_lock *); /* break_lease callback */
        int (*lm_change)(struct file_lock **, int);
  
  locking rules:
-                       file_lock_lock  may block
- lm_compare_owner:     yes             no
- lm_notify:            yes             no
- lm_grant:             no              no
- lm_break:             yes             no
- lm_change             yes             no
+                       inode->i_lock   blocked_lock_lock       may block
+ lm_compare_owner:     yes[1]          maybe                   no
+ lm_owner_key          yes[1]          yes                     no
+ lm_notify:            yes             yes                     no
+ lm_grant:             no              no                      no
+ lm_break:             yes             no                      no
+ lm_change             yes             no                      no
+ [1]:  ->lm_compare_owner and ->lm_owner_key are generally called with
+ *an* inode->i_lock held. It may not be the i_lock of the inode
+ associated with either file_lock argument! This is the case with deadlock
+ detection, since the code has to chase down the owners of locks that may
+ be entirely unrelated to the one on which the lock is being acquired.
+ For deadlock detection however, the blocked_lock_lock is also held. The
+ fact that these locks are held ensures that the file_locks do not
+ disappear out from under you while doing the comparison or generating an
+ owner key.
  
  --------------------------- buffer_head -----------------------------------
  prototypes:
index e6bd1ffd821e28fe05f8046836074b2f6976b6d8,aeff462c72286d6259d74ee90c230ceb560beb2c..1f0ba30ae47e62ff05c4191f10b6b16dd210a1ea
@@@ -360,6 -360,8 +360,8 @@@ struct inode_operations 
        int (*removexattr) (struct dentry *, const char *);
        void (*update_time)(struct inode *, struct timespec *, int);
        int (*atomic_open)(struct inode *, struct dentry *,
+       int (*tmpfile) (struct inode *, struct dentry *, umode_t);
+ } ____cacheline_aligned;
                                struct file *, unsigned open_flag,
                                umode_t create_mode, int *opened);
  };
@@@ -472,6 -474,9 +474,9 @@@ otherwise noted
        component is negative or needs lookup.  Cached positive dentries are
        still handled by f_op->open().
  
+   tmpfile: called in the end of O_TMPFILE open().  Optional, equivalent to
+       atomically creating, opening and unlinking a file in given directory.
  The Address Space Object
  ========================
  
@@@ -549,7 -554,7 +554,7 @@@ struct address_space_operation
  -------------------------------
  
  This describes how the VFS can manipulate mapping of a file to page cache in
 -your filesystem. As of kernel 2.6.22, the following members are defined:
 +your filesystem. The following members are defined:
  
  struct address_space_operations {
        int (*writepage)(struct page *page, struct writeback_control *wbc);
                                loff_t pos, unsigned len, unsigned copied,
                                struct page *page, void *fsdata);
        sector_t (*bmap)(struct address_space *, sector_t);
 -      int (*invalidatepage) (struct page *, unsigned long);
 +      void (*invalidatepage) (struct page *, unsigned int, unsigned int);
        int (*releasepage) (struct page *, int);
        void (*freepage)(struct page *);
        ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
    invalidatepage: If a page has PagePrivate set, then invalidatepage
          will be called when part or all of the page is to be removed
        from the address space.  This generally corresponds to either a
 -      truncation or a complete invalidation of the address space
 -      (in the latter case 'offset' will always be 0).
 -      Any private data associated with the page should be updated
 -      to reflect this truncation.  If offset is 0, then
 -      the private data should be released, because the page
 -      must be able to be completely discarded.  This may be done by
 -        calling the ->releasepage function, but in this case the
 -        release MUST succeed.
 +      truncation, punch hole  or a complete invalidation of the address
 +      space (in the latter case 'offset' will always be 0 and 'length'
 +      will be PAGE_CACHE_SIZE). Any private data associated with the page
 +      should be updated to reflect this truncation.  If offset is 0 and
 +      length is PAGE_CACHE_SIZE, then the private data should be released,
 +      because the page must be able to be completely discarded.  This may
 +      be done by calling the ->releasepage function, but in this case the
 +      release MUST succeed.
  
    releasepage: releasepage is called on PagePrivate pages to indicate
          that the page should be freed if possible.  ->releasepage
@@@ -901,10 -906,8 +906,8 @@@ defined
  struct dentry_operations {
        int (*d_revalidate)(struct dentry *, unsigned int);
        int (*d_weak_revalidate)(struct dentry *, unsigned int);
-       int (*d_hash)(const struct dentry *, const struct inode *,
-                       struct qstr *);
-       int (*d_compare)(const struct dentry *, const struct inode *,
-                       const struct dentry *, const struct inode *,
+       int (*d_hash)(const struct dentry *, struct qstr *);
+       int (*d_compare)(const struct dentry *, const struct dentry *,
                        unsigned int, const char *, const struct qstr *);
        int (*d_delete)(const struct dentry *);
        void (*d_release)(struct dentry *);
  
    d_hash: called when the VFS adds a dentry to the hash table. The first
        dentry passed to d_hash is the parent directory that the name is
-       to be hashed into. The inode is the dentry's inode.
+       to be hashed into.
  
        Same locking and synchronisation rules as d_compare regarding
        what is safe to dereference etc.
  
    d_compare: called to compare a dentry name with a given name. The first
        dentry is the parent of the dentry to be compared, the second is
-       the parent's inode, then the dentry and inode (may be NULL) of the
-       child dentry. len and name string are properties of the dentry to be
-       compared. qstr is the name to compare it with.
+       the child dentry. len and name string are properties of the dentry
+       to be compared. qstr is the name to compare it with.
  
        Must be constant and idempotent, and should not take locks if
-       possible, and should not or store into the dentry or inodes.
-       Should not dereference pointers outside the dentry or inodes without
+       possible, and should not or store into the dentry.
+       Should not dereference pointers outside the dentry without
        lots of care (eg.  d_parent, d_inode, d_name should not be used).
  
        However, our vfsmount is pinned, and RCU held, so the dentries and
        inodes won't disappear, neither will our sb or filesystem module.
-       ->i_sb and ->d_sb may be used.
+       ->d_sb may be used.
  
        It is a tricky calling convention because it needs to be called under
        "rcu-walk", ie. without any locks or references on things.
index 0794aacc928ad649bc9f2fe7370ed7fb30c1aa1a,a9754e84eb8a3a8d5df8267db22456427fe9957b..8647518259f6dd5ab3379babc218d5ef6cf24831
      but WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      GNU General Public License for more details.
 -
 -    You should have received a copy of the GNU General Public License
 -    along with this program; if not, write to the Free Software
 -    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 -
  */
  
  #undef DEBUG
@@@ -531,23 -536,6 +531,23 @@@ static bool comedi_is_subdevice_idle(st
        return (runflags & (SRF_ERROR | SRF_RUNNING)) ? false : true;
  }
  
 +/**
 + * comedi_alloc_spriv() - Allocate memory for the subdevice private data.
 + * @s: comedi_subdevice struct
 + * @size: size of the memory to allocate
 + *
 + * This also sets the subdevice runflags to allow the core to automatically
 + * free the private data during the detach.
 + */
 +void *comedi_alloc_spriv(struct comedi_subdevice *s, size_t size)
 +{
 +      s->private = kzalloc(size, GFP_KERNEL);
 +      if (s->private)
 +              comedi_set_subdevice_runflags(s, ~0, SRF_FREE_SPRIV);
 +      return s->private;
 +}
 +EXPORT_SYMBOL_GPL(comedi_alloc_spriv);
 +
  /*
     This function restores a subdevice to an idle state.
   */
@@@ -677,7 -665,7 +677,7 @@@ static int do_bufconfig_ioctl(struct co
        if (copy_from_user(&bc, arg, sizeof(bc)))
                return -EFAULT;
  
 -      if (bc.subdevice >= dev->n_subdevices || bc.subdevice < 0)
 +      if (bc.subdevice >= dev->n_subdevices)
                return -EINVAL;
  
        s = &dev->subdevices[bc.subdevice];
@@@ -930,7 -918,7 +930,7 @@@ static int do_bufinfo_ioctl(struct come
        if (copy_from_user(&bi, arg, sizeof(bi)))
                return -EFAULT;
  
 -      if (bi.subdevice >= dev->n_subdevices || bi.subdevice < 0)
 +      if (bi.subdevice >= dev->n_subdevices)
                return -EINVAL;
  
        s = &dev->subdevices[bi.subdevice];
@@@ -2329,9 -2317,6 +2329,6 @@@ static int comedi_close(struct inode *i
  
        mutex_unlock(&dev->mutex);
  
-       if (file->f_flags & FASYNC)
-               comedi_fasync(-1, file, 0);
        return 0;
  }
  
diff --combined fs/cifs/file.c
index 4d8ba8d491e5d0be27bfbf8506175f7ffd8ce476,0630710a9c3ff5ffdf2b0588379e1be06b3cb555..91d8629e69a24137e48422cb2620361b4e8e47c2
@@@ -999,7 -999,7 +999,7 @@@ try_again
                rc = wait_event_interruptible(flock->fl_wait, !flock->fl_next);
                if (!rc)
                        goto try_again;
-               locks_delete_block(flock);
+               posix_unblock_lock(flock);
        }
        return rc;
  }
@@@ -1092,6 -1092,7 +1092,7 @@@ struct lock_to_push 
  static int
  cifs_push_posix_locks(struct cifsFileInfo *cfile)
  {
+       struct inode *inode = cfile->dentry->d_inode;
        struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
        struct file_lock *flock, **before;
        unsigned int count = 0, i = 0;
  
        xid = get_xid();
  
-       lock_flocks();
-       cifs_for_each_lock(cfile->dentry->d_inode, before) {
+       spin_lock(&inode->i_lock);
+       cifs_for_each_lock(inode, before) {
                if ((*before)->fl_flags & FL_POSIX)
                        count++;
        }
-       unlock_flocks();
+       spin_unlock(&inode->i_lock);
  
        INIT_LIST_HEAD(&locks_to_send);
  
        }
  
        el = locks_to_send.next;
-       lock_flocks();
-       cifs_for_each_lock(cfile->dentry->d_inode, before) {
+       spin_lock(&inode->i_lock);
+       cifs_for_each_lock(inode, before) {
                flock = *before;
                if ((flock->fl_flags & FL_POSIX) == 0)
                        continue;
                lck->offset = flock->fl_start;
                el = el->next;
        }
-       unlock_flocks();
+       spin_unlock(&inode->i_lock);
  
        list_for_each_entry_safe(lck, tmp, &locks_to_send, llist) {
                int stored_rc;
@@@ -3546,12 -3547,11 +3547,12 @@@ static int cifs_release_page(struct pag
        return cifs_fscache_release_page(page, gfp);
  }
  
 -static void cifs_invalidate_page(struct page *page, unsigned long offset)
 +static void cifs_invalidate_page(struct page *page, unsigned int offset,
 +                               unsigned int length)
  {
        struct cifsInodeInfo *cifsi = CIFS_I(page->mapping->host);
  
 -      if (offset == 0)
 +      if (offset == 0 && length == PAGE_CACHE_SIZE)
                cifs_fscache_invalidate_page(page, &cifsi->vfs_inode);
  }
  
diff --combined fs/dcache.c
index 5a23073138dfe310fb076e81567bac97cd0be9b6,3199fe6863a867a6eefffdd8a1c85f9ebaa343bb..87bdb5329c3c90b99d67f4b5bab3ae0b347d2acf
@@@ -1612,10 -1612,6 +1612,10 @@@ EXPORT_SYMBOL(d_obtain_alias)
   * If a dentry was found and moved, then it is returned.  Otherwise NULL
   * is returned.  This matches the expected return value of ->lookup.
   *
 + * Cluster filesystems may call this function with a negative, hashed dentry.
 + * In that case, we know that the inode will be a regular file, and also this
 + * will only occur during atomic_open. So we need to check for the dentry
 + * being already hashed only in the final case.
   */
  struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
  {
                        security_d_instantiate(dentry, inode);
                        d_rehash(dentry);
                }
 -      } else
 -              d_add(dentry, inode);
 +      } else {
 +              d_instantiate(dentry, inode);
 +              if (d_unhashed(dentry))
 +                      d_rehash(dentry);
 +      }
        return new;
  }
  EXPORT_SYMBOL(d_splice_alias);
@@@ -1730,7 -1723,7 +1730,7 @@@ EXPORT_SYMBOL(d_add_ci)
   * Do the slow-case of the dentry name compare.
   *
   * Unlike the dentry_cmp() function, we need to atomically
-  * load the name, length and inode information, so that the
+  * load the name and length information, so that the
   * filesystem can rely on them, and can use the 'name' and
   * 'len' information without worrying about walking off the
   * end of memory etc.
@@@ -1748,22 -1741,18 +1748,18 @@@ enum slow_d_compare 
  
  static noinline enum slow_d_compare slow_dentry_cmp(
                const struct dentry *parent,
-               struct inode *inode,
                struct dentry *dentry,
                unsigned int seq,
                const struct qstr *name)
  {
        int tlen = dentry->d_name.len;
        const char *tname = dentry->d_name.name;
-       struct inode *i = dentry->d_inode;
  
        if (read_seqcount_retry(&dentry->d_seq, seq)) {
                cpu_relax();
                return D_COMP_SEQRETRY;
        }
-       if (parent->d_op->d_compare(parent, inode,
-                               dentry, i,
-                               tlen, tname, name))
+       if (parent->d_op->d_compare(parent, dentry, tlen, tname, name))
                return D_COMP_NOMATCH;
        return D_COMP_OK;
  }
   * @parent: parent dentry
   * @name: qstr of name we wish to find
   * @seqp: returns d_seq value at the point where the dentry was found
-  * @inode: returns dentry->d_inode when the inode was found valid.
   * Returns: dentry, or NULL
   *
   * __d_lookup_rcu is the dcache lookup function for rcu-walk name
   */
  struct dentry *__d_lookup_rcu(const struct dentry *parent,
                                const struct qstr *name,
-                               unsigned *seqp, struct inode *inode)
+                               unsigned *seqp)
  {
        u64 hashlen = name->hash_len;
        const unsigned char *str = name->name;
  seqretry:
                /*
                 * The dentry sequence count protects us from concurrent
-                * renames, and thus protects inode, parent and name fields.
+                * renames, and thus protects parent and name fields.
                 *
                 * The caller must perform a seqcount check in order
-                * to do anything useful with the returned dentry,
-                * including using the 'd_inode' pointer.
+                * to do anything useful with the returned dentry.
                 *
                 * NOTE! We do a "raw" seqcount_begin here. That means that
                 * we don't wait for the sequence count to stabilize if it
                        continue;
                if (d_unhashed(dentry))
                        continue;
-               *seqp = seq;
  
                if (unlikely(parent->d_flags & DCACHE_OP_COMPARE)) {
                        if (dentry->d_name.hash != hashlen_hash(hashlen))
                                continue;
-                       switch (slow_dentry_cmp(parent, inode, dentry, seq, name)) {
+                       *seqp = seq;
+                       switch (slow_dentry_cmp(parent, dentry, seq, name)) {
                        case D_COMP_OK:
                                return dentry;
                        case D_COMP_NOMATCH:
  
                if (dentry->d_name.hash_len != hashlen)
                        continue;
+               *seqp = seq;
                if (!dentry_cmp(dentry, str, hashlen_len(hashlen)))
                        return dentry;
        }
@@@ -1966,9 -1954,7 +1961,7 @@@ struct dentry *__d_lookup(const struct 
                if (parent->d_flags & DCACHE_OP_COMPARE) {
                        int tlen = dentry->d_name.len;
                        const char *tname = dentry->d_name.name;
-                       if (parent->d_op->d_compare(parent, parent->d_inode,
-                                               dentry, dentry->d_inode,
-                                               tlen, tname, name))
+                       if (parent->d_op->d_compare(parent, dentry, tlen, tname, name))
                                goto next;
                } else {
                        if (dentry->d_name.len != len)
@@@ -2005,7 -1991,7 +1998,7 @@@ struct dentry *d_hash_and_lookup(struc
         */
        name->hash = full_name_hash(name->name, name->len);
        if (dir->d_flags & DCACHE_OP_HASH) {
-               int err = dir->d_op->d_hash(dir, dir->d_inode, name);
+               int err = dir->d_op->d_hash(dir, name);
                if (unlikely(err < 0))
                        return ERR_PTR(err);
        }
@@@ -2975,34 -2961,21 +2968,21 @@@ rename_retry
        goto again;
  }
  
- /**
-  * find_inode_number - check for dentry with name
-  * @dir: directory to check
-  * @name: Name to find.
-  *
-  * Check whether a dentry already exists for the given name,
-  * and return the inode number if it has an inode. Otherwise
-  * 0 is returned.
-  *
-  * This routine is used to post-process directory listings for
-  * filesystems using synthetic inode numbers, and is necessary
-  * to keep getcwd() working.
-  */
-  
- ino_t find_inode_number(struct dentry *dir, struct qstr *name)
+ void d_tmpfile(struct dentry *dentry, struct inode *inode)
  {
-       struct dentry * dentry;
-       ino_t ino = 0;
-       dentry = d_hash_and_lookup(dir, name);
-       if (!IS_ERR_OR_NULL(dentry)) {
-               if (dentry->d_inode)
-                       ino = dentry->d_inode->i_ino;
-               dput(dentry);
-       }
-       return ino;
+       inode_dec_link_count(inode);
+       BUG_ON(dentry->d_name.name != dentry->d_iname ||
+               !hlist_unhashed(&dentry->d_alias) ||
+               !d_unlinked(dentry));
+       spin_lock(&dentry->d_parent->d_lock);
+       spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
+       dentry->d_name.len = sprintf(dentry->d_iname, "#%llu",
+                               (unsigned long long)inode->i_ino);
+       spin_unlock(&dentry->d_lock);
+       spin_unlock(&dentry->d_parent->d_lock);
+       d_instantiate(dentry, inode);
  }
- EXPORT_SYMBOL(find_inode_number);
+ EXPORT_SYMBOL(d_tmpfile);
  
  static __initdata unsigned long dhash_entries;
  static int __init set_dhash_entries(char *str)
diff --combined fs/exec.c
index ffd7a813ad3d06ee1e1de4e996c72282c24e7039,0f6c96c57b2f8c9893062e8a7e08532b54e5a687..03b907cfd76523c690ca7d58ed0448e58ab99b42
+++ b/fs/exec.c
@@@ -110,13 -110,14 +110,14 @@@ SYSCALL_DEFINE1(uselib, const char __us
        static const struct open_flags uselib_flags = {
                .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC,
                .acc_mode = MAY_READ | MAY_EXEC | MAY_OPEN,
-               .intent = LOOKUP_OPEN
+               .intent = LOOKUP_OPEN,
+               .lookup_flags = LOOKUP_FOLLOW,
        };
  
        if (IS_ERR(tmp))
                goto out;
  
-       file = do_filp_open(AT_FDCWD, tmp, &uselib_flags, LOOKUP_FOLLOW);
+       file = do_filp_open(AT_FDCWD, tmp, &uselib_flags);
        putname(tmp);
        error = PTR_ERR(file);
        if (IS_ERR(file))
@@@ -756,10 -757,11 +757,11 @@@ struct file *open_exec(const char *name
        static const struct open_flags open_exec_flags = {
                .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC,
                .acc_mode = MAY_EXEC | MAY_OPEN,
-               .intent = LOOKUP_OPEN
+               .intent = LOOKUP_OPEN,
+               .lookup_flags = LOOKUP_FOLLOW,
        };
  
-       file = do_filp_open(AT_FDCWD, &tmp, &open_exec_flags, LOOKUP_FOLLOW);
+       file = do_filp_open(AT_FDCWD, &tmp, &open_exec_flags);
        if (IS_ERR(file))
                goto out;
  
@@@ -1135,6 -1137,13 +1137,6 @@@ void setup_new_exec(struct linux_binpr
                        set_dumpable(current->mm, suid_dumpable);
        }
  
 -      /*
 -       * Flush performance counters when crossing a
 -       * security domain:
 -       */
 -      if (!get_dumpable(current->mm))
 -              perf_event_exit_task(current);
 -
        /* An exec changes our domain. We are no longer part of the thread
           group */
  
@@@ -1198,15 -1207,6 +1200,15 @@@ void install_exec_creds(struct linux_bi
  
        commit_creds(bprm->cred);
        bprm->cred = NULL;
 +
 +      /*
 +       * Disable monitoring for regular users
 +       * when executing setuid binaries. Must
 +       * wait until new credentials are committed
 +       * by commit_creds() above
 +       */
 +      if (get_dumpable(current->mm) != SUID_DUMP_USER)
 +              perf_event_exit_task(current);
        /*
         * cred_guard_mutex must be held at least to this point to prevent
         * ptrace_attach() from altering our determination of the task's
diff --combined fs/ext3/namei.c
index cea8ecf3e76e47efb977127a95cb7b70a9d5f377,7523c61f796cae7757562054f9387263c8a7599b..998ea111e537e8502dd33b15d5d9eb5f5374306d
@@@ -576,8 -576,11 +576,8 @@@ static int htree_dirblock_to_tree(struc
                if (!ext3_check_dir_entry("htree_dirblock_to_tree", dir, de, bh,
                                        (block<<EXT3_BLOCK_SIZE_BITS(dir->i_sb))
                                                +((char *)de - bh->b_data))) {
 -                      /* On error, skip the f_pos to the next block. */
 -                      dir_file->f_pos = (dir_file->f_pos |
 -                                      (dir->i_sb->s_blocksize - 1)) + 1;
 -                      brelse (bh);
 -                      return count;
 +                      /* silently ignore the rest of the block */
 +                      break;
                }
                ext3fs_dirhash(de->name, de->name_len, hinfo);
                if ((hinfo->hash < start_hash) ||
@@@ -1759,6 -1762,45 +1759,45 @@@ retry
        return err;
  }
  
+ static int ext3_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
+ {
+       handle_t *handle;
+       struct inode *inode;
+       int err, retries = 0;
+       dquot_initialize(dir);
+ retry:
+       handle = ext3_journal_start(dir, EXT3_MAXQUOTAS_INIT_BLOCKS(dir->i_sb) +
+                         4 + EXT3_XATTR_TRANS_BLOCKS);
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+       inode = ext3_new_inode (handle, dir, NULL, mode);
+       err = PTR_ERR(inode);
+       if (!IS_ERR(inode)) {
+               inode->i_op = &ext3_file_inode_operations;
+               inode->i_fop = &ext3_file_operations;
+               ext3_set_aops(inode);
+               err = ext3_orphan_add(handle, inode);
+               if (err)
+                       goto err_drop_inode;
+               mark_inode_dirty(inode);
+               d_tmpfile(dentry, inode);
+               unlock_new_inode(inode);
+       }
+       ext3_journal_stop(handle);
+       if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries))
+               goto retry;
+       return err;
+ err_drop_inode:
+       ext3_journal_stop(handle);
+       unlock_new_inode(inode);
+       iput(inode);
+       return err;
+ }
  static int ext3_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode)
  {
        handle_t *handle;
@@@ -2300,7 -2342,7 +2339,7 @@@ static int ext3_link (struct dentry * o
  
  retry:
        handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
-                                       EXT3_INDEX_EXTRA_TRANS_BLOCKS);
+                                       EXT3_INDEX_EXTRA_TRANS_BLOCKS + 1);
        if (IS_ERR(handle))
                return PTR_ERR(handle);
  
        err = ext3_add_entry(handle, dentry, inode);
        if (!err) {
                ext3_mark_inode_dirty(handle, inode);
+               /* this can happen only for tmpfile being
+                * linked the first time
+                */
+               if (inode->i_nlink == 1)
+                       ext3_orphan_del(handle, inode);
                d_instantiate(dentry, inode);
        } else {
                drop_nlink(inode);
@@@ -2516,6 -2563,7 +2560,7 @@@ const struct inode_operations ext3_dir_
        .mkdir          = ext3_mkdir,
        .rmdir          = ext3_rmdir,
        .mknod          = ext3_mknod,
+       .tmpfile        = ext3_tmpfile,
        .rename         = ext3_rename,
        .setattr        = ext3_setattr,
  #ifdef CONFIG_EXT3_FS_XATTR
diff --combined fs/ext4/file.c
index b19f0a457f329c5fb0f6974f7afff8dc79f1e31c,469361dbe619b4e1eae9b2ed4596753fb0f4ff00..6f4cc567c382b7289e2b35a7038756a581b4cd95
@@@ -312,7 -312,7 +312,7 @@@ static int ext4_find_unwritten_pgoff(st
        blkbits = inode->i_sb->s_blocksize_bits;
        startoff = *offset;
        lastoff = startoff;
 -      endoff = (map->m_lblk + map->m_len) << blkbits;
 +      endoff = (loff_t)(map->m_lblk + map->m_len) << blkbits;
  
        index = startoff >> PAGE_CACHE_SHIFT;
        end = endoff >> PAGE_CACHE_SHIFT;
@@@ -457,7 -457,7 +457,7 @@@ static loff_t ext4_seek_data(struct fil
                ret = ext4_map_blocks(NULL, inode, &map, 0);
                if (ret > 0 && !(map.m_flags & EXT4_MAP_UNWRITTEN)) {
                        if (last != start)
 -                              dataoff = last << blkbits;
 +                              dataoff = (loff_t)last << blkbits;
                        break;
                }
  
                ext4_es_find_delayed_extent_range(inode, last, last, &es);
                if (es.es_len != 0 && in_range(last, es.es_lblk, es.es_len)) {
                        if (last != start)
 -                              dataoff = last << blkbits;
 +                              dataoff = (loff_t)last << blkbits;
                        break;
                }
  
                }
  
                last++;
 -              dataoff = last << blkbits;
 +              dataoff = (loff_t)last << blkbits;
        } while (last <= end);
  
        mutex_unlock(&inode->i_mutex);
        if (dataoff > isize)
                return -ENXIO;
  
-       if (dataoff < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET))
-               return -EINVAL;
-       if (dataoff > maxsize)
-               return -EINVAL;
-       if (dataoff != file->f_pos) {
-               file->f_pos = dataoff;
-               file->f_version = 0;
-       }
-       return dataoff;
+       return vfs_setpos(file, dataoff, maxsize);
  }
  
  /*
@@@ -540,7 -530,7 +530,7 @@@ static loff_t ext4_seek_hole(struct fil
                ret = ext4_map_blocks(NULL, inode, &map, 0);
                if (ret > 0 && !(map.m_flags & EXT4_MAP_UNWRITTEN)) {
                        last += ret;
 -                      holeoff = last << blkbits;
 +                      holeoff = (loff_t)last << blkbits;
                        continue;
                }
  
                ext4_es_find_delayed_extent_range(inode, last, last, &es);
                if (es.es_len != 0 && in_range(last, es.es_lblk, es.es_len)) {
                        last = es.es_lblk + es.es_len;
 -                      holeoff = last << blkbits;
 +                      holeoff = (loff_t)last << blkbits;
                        continue;
                }
  
                                                              &map, &holeoff);
                        if (!unwritten) {
                                last += ret;
 -                              holeoff = last << blkbits;
 +                              holeoff = (loff_t)last << blkbits;
                                continue;
                        }
                }
        if (holeoff > isize)
                holeoff = isize;
  
-       if (holeoff < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET))
-               return -EINVAL;
-       if (holeoff > maxsize)
-               return -EINVAL;
-       if (holeoff != file->f_pos) {
-               file->f_pos = holeoff;
-               file->f_version = 0;
-       }
-       return holeoff;
+       return vfs_setpos(file, holeoff, maxsize);
  }
  
  /*
diff --combined fs/ext4/namei.c
index ab2f6dc44b3abf88b62902433f48a1aa78ba8561,f91002f8c017d14991d3e293947e15065aa0f272..234b834d5a9749991e30a97e24e6017124c4e51d
@@@ -918,8 -918,11 +918,8 @@@ static int htree_dirblock_to_tree(struc
                                bh->b_data, bh->b_size,
                                (block<<EXT4_BLOCK_SIZE_BITS(dir->i_sb))
                                         + ((char *)de - bh->b_data))) {
 -                      /* On error, skip the f_pos to the next block. */
 -                      dir_file->f_pos = (dir_file->f_pos |
 -                                      (dir->i_sb->s_blocksize - 1)) + 1;
 -                      brelse(bh);
 -                      return count;
 +                      /* silently ignore the rest of the block */
 +                      break;
                }
                ext4fs_dirhash(de->name, de->name_len, hinfo);
                if ((hinfo->hash < start_hash) ||
@@@ -2296,6 -2299,45 +2296,45 @@@ retry
        return err;
  }
  
+ static int ext4_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
+ {
+       handle_t *handle;
+       struct inode *inode;
+       int err, retries = 0;
+       dquot_initialize(dir);
+ retry:
+       inode = ext4_new_inode_start_handle(dir, mode,
+                                           NULL, 0, NULL,
+                                           EXT4_HT_DIR,
+                       EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb) +
+                         4 + EXT4_XATTR_TRANS_BLOCKS);
+       handle = ext4_journal_current_handle();
+       err = PTR_ERR(inode);
+       if (!IS_ERR(inode)) {
+               inode->i_op = &ext4_file_inode_operations;
+               inode->i_fop = &ext4_file_operations;
+               ext4_set_aops(inode);
+               err = ext4_orphan_add(handle, inode);
+               if (err)
+                       goto err_drop_inode;
+               mark_inode_dirty(inode);
+               d_tmpfile(dentry, inode);
+               unlock_new_inode(inode);
+       }
+       if (handle)
+               ext4_journal_stop(handle);
+       if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
+               goto retry;
+       return err;
+ err_drop_inode:
+       ext4_journal_stop(handle);
+       unlock_new_inode(inode);
+       iput(inode);
+       return err;
+ }
  struct ext4_dir_entry_2 *ext4_init_dot_dotdot(struct inode *inode,
                          struct ext4_dir_entry_2 *de,
                          int blocksize, int csum_size,
@@@ -2903,7 -2945,7 +2942,7 @@@ static int ext4_link(struct dentry *old
  retry:
        handle = ext4_journal_start(dir, EXT4_HT_DIR,
                (EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
-                EXT4_INDEX_EXTRA_TRANS_BLOCKS));
+                EXT4_INDEX_EXTRA_TRANS_BLOCKS) + 1);
        if (IS_ERR(handle))
                return PTR_ERR(handle);
  
        err = ext4_add_entry(handle, dentry, inode);
        if (!err) {
                ext4_mark_inode_dirty(handle, inode);
+               /* this can happen only for tmpfile being
+                * linked the first time
+                */
+               if (inode->i_nlink == 1)
+                       ext4_orphan_del(handle, inode);
                d_instantiate(dentry, inode);
        } else {
                drop_nlink(inode);
@@@ -3169,6 -3216,7 +3213,7 @@@ const struct inode_operations ext4_dir_
        .mkdir          = ext4_mkdir,
        .rmdir          = ext4_rmdir,
        .mknod          = ext4_mknod,
+       .tmpfile        = ext4_tmpfile,
        .rename         = ext4_rename,
        .setattr        = ext4_setattr,
        .setxattr       = generic_setxattr,
diff --combined fs/fuse/file.c
index 35f2810331427b9c4b660cc6b83ec1b889d6910b,bfb20a8642c3fc271c58aa18c55e4c9411928709..5c121fe19c5f9b6122b687cc14bbcd7b1bbe0dc9
@@@ -548,8 -548,7 +548,7 @@@ static void fuse_aio_complete(struct fu
                        res = io->bytes < 0 ? io->size : io->bytes;
  
                        if (!is_sync_kiocb(io->iocb)) {
-                               struct path *path = &io->iocb->ki_filp->f_path;
-                               struct inode *inode = path->dentry->d_inode;
+                               struct inode *inode = file_inode(io->iocb->ki_filp);
                                struct fuse_conn *fc = get_fuse_conn(inode);
                                struct fuse_inode *fi = get_fuse_inode(inode);
  
@@@ -2470,16 -2469,13 +2469,16 @@@ static long fuse_file_fallocate(struct 
                .mode = mode
        };
        int err;
 +      bool lock_inode = !(mode & FALLOC_FL_KEEP_SIZE) ||
 +                         (mode & FALLOC_FL_PUNCH_HOLE);
  
        if (fc->no_fallocate)
                return -EOPNOTSUPP;
  
 -      if (mode & FALLOC_FL_PUNCH_HOLE) {
 +      if (lock_inode) {
                mutex_lock(&inode->i_mutex);
 -              fuse_set_nowrite(inode);
 +              if (mode & FALLOC_FL_PUNCH_HOLE)
 +                      fuse_set_nowrite(inode);
        }
  
        req = fuse_get_req_nopages(fc);
        fuse_invalidate_attr(inode);
  
  out:
 -      if (mode & FALLOC_FL_PUNCH_HOLE) {
 -              fuse_release_nowrite(inode);
 +      if (lock_inode) {
 +              if (mode & FALLOC_FL_PUNCH_HOLE)
 +                      fuse_release_nowrite(inode);
                mutex_unlock(&inode->i_mutex);
        }
  
diff --combined fs/gfs2/file.c
index f99f9e8a325fa1cd37abcae7f2a09cb21ce6dd14,cebfd404c1d961308bba50215127dffe58b72100..72c3866a73205217b9fe57d7863ce2376ce8002b
@@@ -531,30 -531,21 +531,30 @@@ static int gfs2_mmap(struct file *file
  }
  
  /**
 - * gfs2_open - open a file
 - * @inode: the inode to open
 - * @file: the struct file for this opening
 + * gfs2_open_common - This is common to open and atomic_open
 + * @inode: The inode being opened
 + * @file: The file being opened
   *
 - * Returns: errno
 + * This maybe called under a glock or not depending upon how it has
 + * been called. We must always be called under a glock for regular
 + * files, however. For other file types, it does not matter whether
 + * we hold the glock or not.
 + *
 + * Returns: Error code or 0 for success
   */
  
 -static int gfs2_open(struct inode *inode, struct file *file)
 +int gfs2_open_common(struct inode *inode, struct file *file)
  {
 -      struct gfs2_inode *ip = GFS2_I(inode);
 -      struct gfs2_holder i_gh;
        struct gfs2_file *fp;
 -      int error;
 +      int ret;
 +
 +      if (S_ISREG(inode->i_mode)) {
 +              ret = generic_file_open(inode, file);
 +              if (ret)
 +                      return ret;
 +      }
  
 -      fp = kzalloc(sizeof(struct gfs2_file), GFP_KERNEL);
 +      fp = kzalloc(sizeof(struct gfs2_file), GFP_NOFS);
        if (!fp)
                return -ENOMEM;
  
  
        gfs2_assert_warn(GFS2_SB(inode), !file->private_data);
        file->private_data = fp;
 +      return 0;
 +}
 +
 +/**
 + * gfs2_open - open a file
 + * @inode: the inode to open
 + * @file: the struct file for this opening
 + *
 + * After atomic_open, this function is only used for opening files
 + * which are already cached. We must still get the glock for regular
 + * files to ensure that we have the file size uptodate for the large
 + * file check which is in the common code. That is only an issue for
 + * regular files though.
 + *
 + * Returns: errno
 + */
 +
 +static int gfs2_open(struct inode *inode, struct file *file)
 +{
 +      struct gfs2_inode *ip = GFS2_I(inode);
 +      struct gfs2_holder i_gh;
 +      int error;
 +      bool need_unlock = false;
  
        if (S_ISREG(ip->i_inode.i_mode)) {
                error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY,
                                           &i_gh);
                if (error)
 -                      goto fail;
 +                      return error;
 +              need_unlock = true;
 +      }
  
 -              if (!(file->f_flags & O_LARGEFILE) &&
 -                  i_size_read(inode) > MAX_NON_LFS) {
 -                      error = -EOVERFLOW;
 -                      goto fail_gunlock;
 -              }
 +      error = gfs2_open_common(inode, file);
  
 +      if (need_unlock)
                gfs2_glock_dq_uninit(&i_gh);
 -      }
 -
 -      return 0;
  
 -fail_gunlock:
 -      gfs2_glock_dq_uninit(&i_gh);
 -fail:
 -      file->private_data = NULL;
 -      kfree(fp);
        return error;
  }
  
@@@ -912,7 -889,7 +912,7 @@@ out_uninit
   * cluster; until we do, disable leases (by just returning -EINVAL),
   * unless the administrator has requested purely local locking.
   *
-  * Locking: called under lock_flocks
+  * Locking: called under i_lock
   *
   * Returns: errno
   */
diff --combined fs/splice.c
index d37431dd60a1009f224d4c1bdc65b4fff505d2db,cc53bd04be8f85a4c163b940a8769b7168e05e4e..3b7ee656f3aaeacd719955b2bba80fd5d8d43b0a
@@@ -1098,27 -1098,13 +1098,13 @@@ static long do_splice_from(struct pipe_
  {
        ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
                                loff_t *, size_t, unsigned int);
-       int ret;
-       if (unlikely(!(out->f_mode & FMODE_WRITE)))
-               return -EBADF;
-       if (unlikely(out->f_flags & O_APPEND))
-               return -EINVAL;
-       ret = rw_verify_area(WRITE, out, ppos, len);
-       if (unlikely(ret < 0))
-               return ret;
  
        if (out->f_op && out->f_op->splice_write)
                splice_write = out->f_op->splice_write;
        else
                splice_write = default_file_splice_write;
  
-       file_start_write(out);
-       ret = splice_write(pipe, out, ppos, len, flags);
-       file_end_write(out);
-       return ret;
+       return splice_write(pipe, out, ppos, len, flags);
  }
  
  /*
@@@ -1283,7 -1269,6 +1269,7 @@@ static int direct_splice_actor(struct p
   * @in:               file to splice from
   * @ppos:     input file offset
   * @out:      file to splice to
 + * @opos:     output file offset
   * @len:      number of bytes to splice
   * @flags:    splice modifier flags
   *
@@@ -1307,6 -1292,16 +1293,16 @@@ long do_splice_direct(struct file *in, 
        };
        long ret;
  
+       if (unlikely(!(out->f_mode & FMODE_WRITE)))
+               return -EBADF;
+       if (unlikely(out->f_flags & O_APPEND))
+               return -EINVAL;
+       ret = rw_verify_area(WRITE, out, opos, len);
+       if (unlikely(ret < 0))
+               return ret;
        ret = splice_direct_to_actor(in, &sd, direct_splice_actor);
        if (ret > 0)
                *ppos = sd.pos;
@@@ -1362,7 -1357,19 +1358,19 @@@ static long do_splice(struct file *in, 
                        offset = out->f_pos;
                }
  
+               if (unlikely(!(out->f_mode & FMODE_WRITE)))
+                       return -EBADF;
+               if (unlikely(out->f_flags & O_APPEND))
+                       return -EINVAL;
+               ret = rw_verify_area(WRITE, out, &offset, len);
+               if (unlikely(ret < 0))
+                       return ret;
+               file_start_write(out);
                ret = do_splice_from(ipipe, out, &offset, len, flags);
+               file_end_write(out);
  
                if (!off_out)
                        out->f_pos = offset;
diff --combined include/linux/fs.h
index f8a5240541b77e17df8bf17fa4c10399cdb7fbd2,bccb1924ec93eda2ae891c7cd1f6ab970ffd6a9d..2b82c80414900fc22d152b6ad9eb71d8d790767a
@@@ -364,7 -364,7 +364,7 @@@ struct address_space_operations 
  
        /* Unfortunately this kludge is needed for FIBMAP. Don't use it */
        sector_t (*bmap)(struct address_space *, sector_t);
 -      void (*invalidatepage) (struct page *, unsigned long);
 +      void (*invalidatepage) (struct page *, unsigned int, unsigned int);
        int (*releasepage) (struct page *, gfp_t);
        void (*freepage)(struct page *);
        ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
@@@ -908,6 -908,7 +908,7 @@@ struct file_lock_operations 
  
  struct lock_manager_operations {
        int (*lm_compare_owner)(struct file_lock *, struct file_lock *);
+       unsigned long (*lm_owner_key)(struct file_lock *);
        void (*lm_notify)(struct file_lock *);  /* unblock callback */
        int (*lm_grant)(struct file_lock *, struct file_lock *, int);
        void (*lm_break)(struct file_lock *);
@@@ -926,9 -927,27 +927,27 @@@ int locks_in_grace(struct net *)
  /* that will die - we need it for nfs_lock_info */
  #include <linux/nfs_fs_i.h>
  
+ /*
+  * struct file_lock represents a generic "file lock". It's used to represent
+  * POSIX byte range locks, BSD (flock) locks, and leases. It's important to
+  * note that the same struct is used to represent both a request for a lock and
+  * the lock itself, but the same object is never used for both.
+  *
+  * FIXME: should we create a separate "struct lock_request" to help distinguish
+  * these two uses?
+  *
+  * The i_flock list is ordered by:
+  *
+  * 1) lock type -- FL_LEASEs first, then FL_FLOCK, and finally FL_POSIX
+  * 2) lock owner
+  * 3) lock range start
+  * 4) lock range end
+  *
+  * Obviously, the last two criteria only matter for POSIX locks.
+  */
  struct file_lock {
        struct file_lock *fl_next;      /* singly linked list for this inode  */
-       struct list_head fl_link;       /* doubly linked list of all locks */
+       struct hlist_node fl_link;      /* node in global lists */
        struct list_head fl_block;      /* circular list of blocked processes */
        fl_owner_t fl_owner;
        unsigned int fl_flags;
@@@ -994,7 -1013,7 +1013,7 @@@ extern void locks_release_private(struc
  extern void posix_test_lock(struct file *, struct file_lock *);
  extern int posix_lock_file(struct file *, struct file_lock *, struct file_lock *);
  extern int posix_lock_file_wait(struct file *, struct file_lock *);
- extern int posix_unblock_lock(struct file *, struct file_lock *);
+ extern int posix_unblock_lock(struct file_lock *);
  extern int vfs_test_lock(struct file *, struct file_lock *);
  extern int vfs_lock_file(struct file *, unsigned int, struct file_lock *, struct file_lock *);
  extern int vfs_cancel_lock(struct file *filp, struct file_lock *fl);
@@@ -1006,9 -1025,6 +1025,6 @@@ extern int vfs_setlease(struct file *, 
  extern int lease_modify(struct file_lock **, int);
  extern int lock_may_read(struct inode *, loff_t start, unsigned long count);
  extern int lock_may_write(struct inode *, loff_t start, unsigned long count);
- extern void locks_delete_block(struct file_lock *waiter);
- extern void lock_flocks(void);
- extern void unlock_flocks(void);
  #else /* !CONFIG_FILE_LOCKING */
  static inline int fcntl_getlk(struct file *file, struct flock __user *user)
  {
@@@ -1084,8 -1100,7 +1100,7 @@@ static inline int posix_lock_file_wait(
        return -ENOLCK;
  }
  
- static inline int posix_unblock_lock(struct file *filp,
-                                    struct file_lock *waiter)
+ static inline int posix_unblock_lock(struct file_lock *waiter)
  {
        return -ENOENT;
  }
@@@ -1150,19 -1165,6 +1165,6 @@@ static inline int lock_may_write(struc
  {
        return 1;
  }
- static inline void locks_delete_block(struct file_lock *waiter)
- {
- }
- static inline void lock_flocks(void)
- {
- }
- static inline void unlock_flocks(void)
- {
- }
  #endif /* !CONFIG_FILE_LOCKING */
  
  
@@@ -1580,6 -1582,7 +1582,7 @@@ struct inode_operations 
        int (*atomic_open)(struct inode *, struct dentry *,
                           struct file *, unsigned open_flag,
                           umode_t create_mode, int *opened);
+       int (*tmpfile) (struct inode *, struct dentry *, umode_t);
  } ____cacheline_aligned;
  
  ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
@@@ -1743,6 -1746,7 +1746,7 @@@ struct super_operations 
  #define I_REFERENCED          (1 << 8)
  #define __I_DIO_WAKEUP                9
  #define I_DIO_WAKEUP          (1 << I_DIO_WAKEUP)
+ #define I_LINKABLE            (1 << 10)
  
  #define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES)
  
@@@ -1896,7 -1900,6 +1900,6 @@@ extern int current_umask(void)
  extern struct kobject *fs_kobj;
  
  #define MAX_RW_COUNT (INT_MAX & PAGE_CACHE_MASK)
- extern int rw_verify_area(int, struct file *, loff_t *, size_t);
  
  #define FLOCK_VERIFY_READ  1
  #define FLOCK_VERIFY_WRITE 2
@@@ -2309,7 -2312,6 +2312,6 @@@ extern struct file * open_exec(const ch
  /* fs/dcache.c -- generic fs support functions */
  extern int is_subdir(struct dentry *, struct dentry *);
  extern int path_is_under(struct path *, struct path *);
- extern ino_t find_inode_number(struct dentry *, struct qstr *);
  
  #include <linux/err.h>
  
@@@ -2424,9 -2426,12 +2426,12 @@@ extern voi
  file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping);
  extern loff_t noop_llseek(struct file *file, loff_t offset, int whence);
  extern loff_t no_llseek(struct file *file, loff_t offset, int whence);
+ extern loff_t vfs_setpos(struct file *file, loff_t offset, loff_t maxsize);
  extern loff_t generic_file_llseek(struct file *file, loff_t offset, int whence);
  extern loff_t generic_file_llseek_size(struct file *file, loff_t offset,
                int whence, loff_t maxsize, loff_t eof);
+ extern loff_t fixed_size_llseek(struct file *file, loff_t offset,
+               int whence, loff_t size);
  extern int generic_file_open(struct inode * inode, struct file * filp);
  extern int nonseekable_open(struct inode * inode, struct file * filp);