[NFS]: Check that the server returns a valid regular file to our OPEN request
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Tue, 18 Oct 2005 21:20:18 +0000 (14:20 -0700)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Tue, 18 Oct 2005 21:20:18 +0000 (14:20 -0700)
 Since it appears that some servers don't...

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
fs/nfs/dir.c
fs/nfs/nfs4proc.c

index a6e251f..ac331d2 100644 (file)
@@ -957,10 +957,12 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
                                res = NULL;
                                goto out;
                        /* This turned out not to be a regular file */
+                       case -EISDIR:
+                       case -ENOTDIR:
+                               goto no_open;
                        case -ELOOP:
                                if (!(nd->intent.open.flags & O_NOFOLLOW))
                                        goto no_open;
-                       /* case -EISDIR: */
                        /* case -EINVAL: */
                        default:
                                goto out;
index c9ecb81..3db1c9f 100644 (file)
@@ -419,6 +419,22 @@ static int _nfs4_proc_open(struct inode *dir, struct nfs4_state_owner  *sp, stru
        o_arg->clientid = sp->so_client->cl_clientid;
 
        status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
+       if (status == 0) {
+               /* OPEN on anything except a regular file is disallowed in NFSv4 */
+               switch (o_res->f_attr->mode & S_IFMT) {
+                       case S_IFREG:
+                               break;
+                       case S_IFLNK:
+                               status = -ELOOP;
+                               break;
+                       case S_IFDIR:
+                               status = -EISDIR;
+                               break;
+                       default:
+                               status = -ENOTDIR;
+               }
+       }
+
        nfs_increment_open_seqid(status, o_arg->seqid);
        if (status != 0)
                goto out;