Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
[linux-2.6.git] / fs / nfsd / vfs.c
index 0f79e33..641117f 100644 (file)
@@ -1,4 +1,3 @@
-#define MSNFS  /* HACK HACK */
 /*
  * File operations used by nfsd. Some of these have been ripped from
  * other parts of the kernel because they weren't exported, others
@@ -35,8 +34,8 @@
 #endif /* CONFIG_NFSD_V3 */
 
 #ifdef CONFIG_NFSD_V4
-#include <linux/nfs4_acl.h>
-#include <linux/nfsd_idmap.h>
+#include "acl.h"
+#include "idmap.h"
 #endif /* CONFIG_NFSD_V4 */
 
 #include "nfsd.h"
@@ -274,6 +273,13 @@ out:
        return err;
 }
 
+static int nfsd_break_lease(struct inode *inode)
+{
+       if (!S_ISREG(inode->i_mode))
+               return 0;
+       return break_lease(inode, O_WRONLY | O_NONBLOCK);
+}
+
 /*
  * Commit metadata changes to stable storage.
  */
@@ -376,16 +382,6 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
                                goto out;
                }
 
-               /*
-                * If we are changing the size of the file, then
-                * we need to break all leases.
-                */
-               host_err = break_lease(inode, O_WRONLY | O_NONBLOCK);
-               if (host_err == -EWOULDBLOCK)
-                       host_err = -ETIMEDOUT;
-               if (host_err) /* ENOMEM or EWOULDBLOCK */
-                       goto out_nfserr;
-
                host_err = get_write_access(inode);
                if (host_err)
                        goto out_nfserr;
@@ -426,7 +422,11 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
 
        err = nfserr_notsync;
        if (!check_guard || guardtime == inode->i_ctime.tv_sec) {
+               host_err = nfsd_break_lease(inode);
+               if (host_err)
+                       goto out_nfserr;
                fh_lock(fhp);
+
                host_err = notify_change(dentry, iap);
                err = nfserrno(host_err);
                fh_unlock(fhp);
@@ -753,8 +753,6 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
         */
        if (!(access & NFSD_MAY_NOT_BREAK_LEASE))
                host_err = break_lease(inode, O_NONBLOCK | ((access & NFSD_MAY_WRITE) ? O_WRONLY : 0));
-       if (host_err == -EWOULDBLOCK)
-               host_err = -ETIMEDOUT;
        if (host_err) /* NOMEM or WOULDBLOCK */
                goto out_nfserr;
 
@@ -875,15 +873,6 @@ static int nfsd_direct_splice_actor(struct pipe_inode_info *pipe,
        return __splice_from_pipe(pipe, sd, nfsd_splice_actor);
 }
 
-static inline int svc_msnfs(struct svc_fh *ffhp)
-{
-#ifdef MSNFS
-       return (ffhp->fh_export->ex_flags & NFSEXP_MSNFS);
-#else
-       return 0;
-#endif
-}
-
 static __be32
 nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
               loff_t offset, struct kvec *vec, int vlen, unsigned long *count)
@@ -896,9 +885,6 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
        err = nfserr_perm;
        inode = file->f_path.dentry->d_inode;
 
-       if (svc_msnfs(fhp) && !lock_may_read(inode, offset, *count))
-               goto out;
-
        if (file->f_op->splice_read && rqstp->rq_splice_ok) {
                struct splice_desc sd = {
                        .len            = 0,
@@ -923,7 +909,6 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
                fsnotify_access(file);
        } else 
                err = nfserrno(host_err);
-out:
        return err;
 }
 
@@ -988,14 +973,6 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
        int                     stable = *stablep;
        int                     use_wgather;
 
-#ifdef MSNFS
-       err = nfserr_perm;
-
-       if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
-               (!lock_may_write(file->f_path.dentry->d_inode, offset, *cnt)))
-               goto out;
-#endif
-
        dentry = file->f_path.dentry;
        inode = dentry->d_inode;
        exp   = fhp->fh_export;
@@ -1046,7 +1023,6 @@ out_nfserr:
                err = 0;
        else
                err = nfserrno(host_err);
-out:
        return err;
 }
 
@@ -1666,6 +1642,12 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
                err = nfserrno(host_err);
                goto out_dput;
        }
+       err = nfserr_noent;
+       if (!dold->d_inode)
+               goto out_drop_write;
+       host_err = nfsd_break_lease(dold->d_inode);
+       if (host_err)
+               goto out_drop_write;
        host_err = vfs_link(dold, dirp, dnew);
        if (!host_err) {
                err = nfserrno(commit_metadata(ffhp));
@@ -1677,6 +1659,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
                else
                        err = nfserrno(host_err);
        }
+out_drop_write:
        mnt_drop_write(tfhp->fh_export->ex_path.mnt);
 out_dput:
        dput(dnew);
@@ -1751,12 +1734,6 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
        if (ndentry == trap)
                goto out_dput_new;
 
-       if (svc_msnfs(ffhp) &&
-               ((odentry->d_count > 1) || (ndentry->d_count > 1))) {
-                       host_err = -EPERM;
-                       goto out_dput_new;
-       }
-
        host_err = -EXDEV;
        if (ffhp->fh_export->ex_path.mnt != tfhp->fh_export->ex_path.mnt)
                goto out_dput_new;
@@ -1764,15 +1741,17 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
        if (host_err)
                goto out_dput_new;
 
+       host_err = nfsd_break_lease(odentry->d_inode);
+       if (host_err)
+               goto out_drop_write;
        host_err = vfs_rename(fdir, odentry, tdir, ndentry);
        if (!host_err) {
                host_err = commit_metadata(tfhp);
                if (!host_err)
                        host_err = commit_metadata(ffhp);
        }
-
+out_drop_write:
        mnt_drop_write(ffhp->fh_export->ex_path.mnt);
-
  out_dput_new:
        dput(ndentry);
  out_dput_old:
@@ -1835,18 +1814,14 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
        if (host_err)
                goto out_nfserr;
 
-       if (type != S_IFDIR) { /* It's UNLINK */
-#ifdef MSNFS
-               if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
-                       (rdentry->d_count > 1)) {
-                       host_err = -EPERM;
-               } else
-#endif
+       host_err = nfsd_break_lease(rdentry->d_inode);
+       if (host_err)
+               goto out_put;
+       if (type != S_IFDIR)
                host_err = vfs_unlink(dirp, rdentry);
-       } else { /* It's RMDIR */
+       else
                host_err = vfs_rmdir(dirp, rdentry);
-       }
-
+out_put:
        dput(rdentry);
 
        if (!host_err)