Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs into for-2.6.34-incoming
authorJ. Bruce Fields <bfields@citi.umich.edu>
Thu, 4 Mar 2010 17:03:16 +0000 (12:03 -0500)
committerJ. Bruce Fields <bfields@citi.umich.edu>
Thu, 4 Mar 2010 17:04:51 +0000 (12:04 -0500)
Resolve merge conflict in fs/xfs/linux-2.6/xfs_export.c.

1  2 
fs/nfsd/vfs.c
fs/xfs/linux-2.6/xfs_export.c

diff --combined fs/nfsd/vfs.c
@@@ -27,8 -27,6 +27,8 @@@
  #include <linux/jhash.h>
  #include <linux/ima.h>
  #include <asm/uaccess.h>
 +#include <linux/exportfs.h>
 +#include <linux/writeback.h>
  
  #ifdef CONFIG_NFSD_V3
  #include "xdr3.h"
@@@ -273,32 -271,6 +273,32 @@@ out
        return err;
  }
  
 +/*
 + * Commit metadata changes to stable storage.
 + */
 +static int
 +commit_metadata(struct svc_fh *fhp)
 +{
 +      struct inode *inode = fhp->fh_dentry->d_inode;
 +      const struct export_operations *export_ops = inode->i_sb->s_export_op;
 +      int error = 0;
 +
 +      if (!EX_ISSYNC(fhp->fh_export))
 +              return 0;
 +
 +      if (export_ops->commit_metadata) {
 +              error = export_ops->commit_metadata(inode);
 +      } else {
 +              struct writeback_control wbc = {
 +                      .sync_mode = WB_SYNC_ALL,
 +                      .nr_to_write = 0, /* metadata only */
 +              };
 +
 +              error = sync_inode(inode, &wbc);
 +      }
 +
 +      return error;
 +}
  
  /*
   * Set various file attributes.
@@@ -780,6 -752,8 +780,8 @@@ nfsd_open(struct svc_rqst *rqstp, struc
                            flags, current_cred());
        if (IS_ERR(*filp))
                host_err = PTR_ERR(*filp);
+       else
+               host_err = ima_file_check(*filp, access);
  out_nfserr:
        err = nfserrno(host_err);
  out:
@@@ -797,6 -771,43 +799,6 @@@ nfsd_close(struct file *filp
  }
  
  /*
 - * Sync a file
 - * As this calls fsync (not fdatasync) there is no need for a write_inode
 - * after it.
 - */
 -static inline int nfsd_dosync(struct file *filp, struct dentry *dp,
 -                            const struct file_operations *fop)
 -{
 -      struct inode *inode = dp->d_inode;
 -      int (*fsync) (struct file *, struct dentry *, int);
 -      int err;
 -
 -      err = filemap_write_and_wait(inode->i_mapping);
 -      if (err == 0 && fop && (fsync = fop->fsync))
 -              err = fsync(filp, dp, 0);
 -      return err;
 -}
 -
 -static int
 -nfsd_sync(struct file *filp)
 -{
 -        int err;
 -      struct inode *inode = filp->f_path.dentry->d_inode;
 -      dprintk("nfsd: sync file %s\n", filp->f_path.dentry->d_name.name);
 -      mutex_lock(&inode->i_mutex);
 -      err=nfsd_dosync(filp, filp->f_path.dentry, filp->f_op);
 -      mutex_unlock(&inode->i_mutex);
 -
 -      return err;
 -}
 -
 -int
 -nfsd_sync_dir(struct dentry *dp)
 -{
 -      return nfsd_dosync(NULL, dp, dp->d_inode->i_fop);
 -}
 -
 -/*
   * Obtain the readahead parameters for the file
   * specified by (dev, ino).
   */
@@@ -999,7 -1010,7 +1001,7 @@@ static int wait_for_concurrent_writes(s
  
        if (inode->i_state & I_DIRTY) {
                dprintk("nfsd: write sync %d\n", task_pid_nr(current));
 -              err = nfsd_sync(file);
 +              err = vfs_fsync(file, file->f_path.dentry, 0);
        }
        last_ino = inode->i_ino;
        last_dev = inode->i_sb->s_dev;
@@@ -1147,9 -1158,8 +1149,9 @@@ out
  #ifdef CONFIG_NFSD_V3
  /*
   * Commit all pending writes to stable storage.
 - * Strictly speaking, we could sync just the indicated file region here,
 - * but there's currently no way we can ask the VFS to do so.
 + *
 + * Note: we only guarantee that data that lies within the range specified
 + * by the 'offset' and 'count' parameters will be synced.
   *
   * Unfortunately we cannot lock the file to make sure we return full WCC
   * data to the client, as locking happens lower down in the filesystem.
@@@ -1159,32 -1169,23 +1161,32 @@@ nfsd_commit(struct svc_rqst *rqstp, str
                 loff_t offset, unsigned long count)
  {
        struct file     *file;
 -      __be32          err;
 +      loff_t          end = LLONG_MAX;
 +      __be32          err = nfserr_inval;
  
 -      if ((u64)count > ~(u64)offset)
 -              return nfserr_inval;
 +      if (offset < 0)
 +              goto out;
 +      if (count != 0) {
 +              end = offset + (loff_t)count - 1;
 +              if (end < offset)
 +                      goto out;
 +      }
  
        err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_WRITE, &file);
        if (err)
 -              return err;
 +              goto out;
        if (EX_ISSYNC(fhp->fh_export)) {
 -              if (file->f_op && file->f_op->fsync) {
 -                      err = nfserrno(nfsd_sync(file));
 -              } else {
 +              int err2 = vfs_fsync_range(file, file->f_path.dentry,
 +                              offset, end, 0);
 +
 +              if (err2 != -EINVAL)
 +                      err = nfserrno(err2);
 +              else
                        err = nfserr_notsupp;
        }
  
        nfsd_close(file);
 +out:
        return err;
  }
  #endif /* CONFIG_NFSD_V3 */
@@@ -1337,14 -1338,12 +1339,14 @@@ nfsd_create(struct svc_rqst *rqstp, str
                goto out_nfserr;
        }
  
 -      if (EX_ISSYNC(fhp->fh_export)) {
 -              err = nfserrno(nfsd_sync_dir(dentry));
 -              write_inode_now(dchild->d_inode, 1);
 -      }
 +      err = nfsd_create_setattr(rqstp, resfhp, iap);
  
 -      err2 = nfsd_create_setattr(rqstp, resfhp, iap);
 +      /*
 +       * nfsd_setattr already committed the child.  Transactional filesystems
 +       * had a chance to commit changes for both parent and child
 +       * simultaneously making the following commit_metadata a noop.
 +       */
 +      err2 = nfserrno(commit_metadata(fhp));
        if (err2)
                err = err2;
        mnt_drop_write(fhp->fh_export->ex_path.mnt);
@@@ -1376,6 -1375,7 +1378,6 @@@ nfsd_create_v3(struct svc_rqst *rqstp, 
        struct dentry   *dentry, *dchild = NULL;
        struct inode    *dirp;
        __be32          err;
 -      __be32          err2;
        int             host_err;
        __u32           v_mtime=0, v_atime=0;
  
        if (created)
                *created = 1;
  
 -      if (EX_ISSYNC(fhp->fh_export)) {
 -              err = nfserrno(nfsd_sync_dir(dentry));
 -              /* setattr will sync the child (or not) */
 -      }
 -
        nfsd_check_ignore_resizing(iap);
  
        if (createmode == NFS3_CREATE_EXCLUSIVE) {
        }
  
   set_attr:
 -      err2 = nfsd_create_setattr(rqstp, resfhp, iap);
 -      if (err2)
 -              err = err2;
 +      err = nfsd_create_setattr(rqstp, resfhp, iap);
 +
 +      /*
 +       * nfsd_setattr already committed the child (and possibly also the parent).
 +       */
 +      if (!err)
 +              err = nfserrno(commit_metadata(fhp));
  
        mnt_drop_write(fhp->fh_export->ex_path.mnt);
        /*
@@@ -1605,9 -1606,12 +1607,9 @@@ nfsd_symlink(struct svc_rqst *rqstp, st
                }
        } else
                host_err = vfs_symlink(dentry->d_inode, dnew, path);
 -
 -      if (!host_err) {
 -              if (EX_ISSYNC(fhp->fh_export))
 -                      host_err = nfsd_sync_dir(dentry);
 -      }
        err = nfserrno(host_err);
 +      if (!err)
 +              err = nfserrno(commit_metadata(fhp));
        fh_unlock(fhp);
  
        mnt_drop_write(fhp->fh_export->ex_path.mnt);
@@@ -1669,9 -1673,11 +1671,9 @@@ nfsd_link(struct svc_rqst *rqstp, struc
        }
        host_err = vfs_link(dold, dirp, dnew);
        if (!host_err) {
 -              if (EX_ISSYNC(ffhp->fh_export)) {
 -                      err = nfserrno(nfsd_sync_dir(ddir));
 -                      write_inode_now(dest, 1);
 -              }
 -              err = 0;
 +              err = nfserrno(commit_metadata(ffhp));
 +              if (!err)
 +                      err = nfserrno(commit_metadata(tfhp));
        } else {
                if (host_err == -EXDEV && rqstp->rq_vers == 2)
                        err = nfserr_acces;
@@@ -1767,10 -1773,10 +1769,10 @@@ nfsd_rename(struct svc_rqst *rqstp, str
                goto out_dput_new;
  
        host_err = vfs_rename(fdir, odentry, tdir, ndentry);
 -      if (!host_err && EX_ISSYNC(tfhp->fh_export)) {
 -              host_err = nfsd_sync_dir(tdentry);
 +      if (!host_err) {
 +              host_err = commit_metadata(tfhp);
                if (!host_err)
 -                      host_err = nfsd_sync_dir(fdentry);
 +                      host_err = commit_metadata(ffhp);
        }
  
        mnt_drop_write(ffhp->fh_export->ex_path.mnt);
@@@ -1851,9 -1857,12 +1853,9 @@@ nfsd_unlink(struct svc_rqst *rqstp, str
  
        dput(rdentry);
  
 -      if (host_err)
 -              goto out_drop;
 -      if (EX_ISSYNC(fhp->fh_export))
 -              host_err = nfsd_sync_dir(dentry);
 +      if (!host_err)
 +              host_err = commit_metadata(fhp);
  
 -out_drop:
        mnt_drop_write(fhp->fh_export->ex_path.mnt);
  out_nfserr:
        err = nfserrno(host_err);
@@@ -2120,7 -2129,6 +2122,6 @@@ nfsd_permission(struct svc_rqst *rqstp
         */
        path.mnt = exp->ex_path.mnt;
        path.dentry = dentry;
-       err = ima_path_check(&path, acc & (MAY_READ | MAY_WRITE | MAY_EXEC));
  nfsd_out:
        return err? nfserrno(err) : 0;
  }
@@@ -29,7 -29,6 +29,7 @@@
  #include "xfs_vnodeops.h"
  #include "xfs_bmap_btree.h"
  #include "xfs_inode.h"
 +#include "xfs_inode_item.h"
  
  /*
   * Note that we only accept fileids which are long enough rather than allow
@@@ -216,28 -215,9 +216,28 @@@ xfs_fs_get_parent
        return d_obtain_alias(VFS_I(cip));
  }
  
-               error = _xfs_log_force(mp, ip->i_itemp->ili_last_lsn,
-                               XFS_LOG_FORCE | XFS_LOG_SYNC, NULL);
 +STATIC int
 +xfs_fs_nfs_commit_metadata(
 +      struct inode            *inode)
 +{
 +      struct xfs_inode        *ip = XFS_I(inode);
 +      struct xfs_mount        *mp = ip->i_mount;
 +      int                     error = 0;
 +
 +      xfs_ilock(ip, XFS_ILOCK_SHARED);
 +      if (xfs_ipincount(ip)) {
++              error = _xfs_log_force_lsn(mp, ip->i_itemp->ili_last_lsn,
++                              XFS_LOG_SYNC, NULL);
 +      }
 +      xfs_iunlock(ip, XFS_ILOCK_SHARED);
 +
 +      return error;
 +}
 +
  const struct export_operations xfs_export_operations = {
        .encode_fh              = xfs_fs_encode_fh,
        .fh_to_dentry           = xfs_fs_fh_to_dentry,
        .fh_to_parent           = xfs_fs_fh_to_parent,
        .get_parent             = xfs_fs_get_parent,
 +      .commit_metadata        = xfs_fs_nfs_commit_metadata,
  };