Merge branch 'for-3.4' of git://linux-nfs.org/~bfields/linux
[linux-2.6.git] / fs / nfsd / vfs.c
index e59f71d..296d671 100644 (file)
@@ -737,12 +737,13 @@ static int nfsd_open_break_lease(struct inode *inode, int access)
 
 /*
  * Open an existing file or directory.
- * The access argument indicates the type of open (read/write/lock)
+ * The may_flags argument indicates the type of open (read/write/lock)
+ * and additional flags.
  * N.B. After this call fhp needs an fh_put
  */
 __be32
 nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
-                       int access, struct file **filp)
+                       int may_flags, struct file **filp)
 {
        struct dentry   *dentry;
        struct inode    *inode;
@@ -757,7 +758,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
         * and (hopefully) checked permission - so allow OWNER_OVERRIDE
         * in case a chmod has now revoked permission.
         */
-       err = fh_verify(rqstp, fhp, type, access | NFSD_MAY_OWNER_OVERRIDE);
+       err = fh_verify(rqstp, fhp, type, may_flags | NFSD_MAY_OWNER_OVERRIDE);
        if (err)
                goto out;
 
@@ -768,7 +769,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
         * or any access when mandatory locking enabled
         */
        err = nfserr_perm;
-       if (IS_APPEND(inode) && (access & NFSD_MAY_WRITE))
+       if (IS_APPEND(inode) && (may_flags & NFSD_MAY_WRITE))
                goto out;
        /*
         * We must ignore files (but only files) which might have mandatory
@@ -781,12 +782,12 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
        if (!inode->i_fop)
                goto out;
 
-       host_err = nfsd_open_break_lease(inode, access);
+       host_err = nfsd_open_break_lease(inode, may_flags);
        if (host_err) /* NOMEM or WOULDBLOCK */
                goto out_nfserr;
 
-       if (access & NFSD_MAY_WRITE) {
-               if (access & NFSD_MAY_READ)
+       if (may_flags & NFSD_MAY_WRITE) {
+               if (may_flags & NFSD_MAY_READ)
                        flags = O_RDWR|O_LARGEFILE;
                else
                        flags = O_WRONLY|O_LARGEFILE;
@@ -795,8 +796,15 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
                            flags, current_cred());
        if (IS_ERR(*filp))
                host_err = PTR_ERR(*filp);
-       else
-               host_err = ima_file_check(*filp, access);
+       else {
+               host_err = ima_file_check(*filp, may_flags);
+
+               if (may_flags & NFSD_MAY_64BIT_COOKIE)
+                       (*filp)->f_mode |= FMODE_64BITHASH;
+               else
+                       (*filp)->f_mode |= FMODE_32BITHASH;
+       }
+
 out_nfserr:
        err = nfserrno(host_err);
 out:
@@ -2021,8 +2029,13 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp,
        __be32          err;
        struct file     *file;
        loff_t          offset = *offsetp;
+       int             may_flags = NFSD_MAY_READ;
+
+       /* NFSv2 only supports 32 bit cookies */
+       if (rqstp->rq_vers > 2)
+               may_flags |= NFSD_MAY_64BIT_COOKIE;
 
-       err = nfsd_open(rqstp, fhp, S_IFDIR, NFSD_MAY_READ, &file);
+       err = nfsd_open(rqstp, fhp, S_IFDIR, may_flags, &file);
        if (err)
                goto out;