NFSv4: Allow the state manager to mark an open_owner as being recovered
[linux-2.6-block.git] / fs / nfs / nfs4proc.c
index 493f0f41c5547d94eecf12de33bc8acf1545c2f7..62fa4001e47ae1846cda297a26b0ca035c56dc4d 100644 (file)
@@ -64,7 +64,7 @@
 #include "pnfs.h"
 #include "netns.h"
 #include "nfs4session.h"
-
+#include "fscache.h"
 
 #define NFSDBG_FACILITY                NFSDBG_PROC
 
@@ -734,6 +734,7 @@ static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo)
        if (!cinfo->atomic || cinfo->before != dir->i_version)
                nfs_force_lookup_revalidate(dir);
        dir->i_version = cinfo->after;
+       nfs_fscache_invalidate(dir);
        spin_unlock(&dir->i_lock);
 }
 
@@ -1625,7 +1626,8 @@ static int _nfs4_recover_proc_open(struct nfs4_opendata *data)
 
 static int nfs4_opendata_access(struct rpc_cred *cred,
                                struct nfs4_opendata *opendata,
-                               struct nfs4_state *state, fmode_t fmode)
+                               struct nfs4_state *state, fmode_t fmode,
+                               int openflags)
 {
        struct nfs_access_entry cache;
        u32 mask;
@@ -1637,11 +1639,14 @@ static int nfs4_opendata_access(struct rpc_cred *cred,
 
        mask = 0;
        /* don't check MAY_WRITE - a newly created file may not have
-        * write mode bits, but POSIX allows the creating process to write */
-       if (fmode & FMODE_READ)
-               mask |= MAY_READ;
-       if (fmode & FMODE_EXEC)
-               mask |= MAY_EXEC;
+        * write mode bits, but POSIX allows the creating process to write.
+        * use openflags to check for exec, because fmode won't
+        * always have FMODE_EXEC set when file open for exec. */
+       if (openflags & __FMODE_EXEC) {
+               /* ONLY check for exec rights */
+               mask = MAY_EXEC;
+       } else if (fmode & FMODE_READ)
+               mask = MAY_READ;
 
        cache.cred = cred;
        cache.jiffies = jiffies;
@@ -1895,7 +1900,7 @@ static int _nfs4_do_open(struct inode *dir,
        if (server->caps & NFS_CAP_POSIX_LOCK)
                set_bit(NFS_STATE_POSIX_LOCKS, &state->flags);
 
-       status = nfs4_opendata_access(cred, opendata, state, fmode);
+       status = nfs4_opendata_access(cred, opendata, state, fmode, flags);
        if (status != 0)
                goto err_opendata_put;
 
@@ -2083,7 +2088,7 @@ static void nfs4_free_closedata(void *data)
        nfs4_put_open_state(calldata->state);
        nfs_free_seqid(calldata->arg.seqid);
        nfs4_put_state_owner(sp);
-       nfs_sb_deactive_async(sb);
+       nfs_sb_deactive(sb);
        kfree(calldata);
 }