diff options
Diffstat (limited to 'fs/nfs/callback_proc.c')
-rw-r--r-- | fs/nfs/callback_proc.c | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c new file mode 100644 index 000000000000..ece27e42b93b --- /dev/null +++ b/fs/nfs/callback_proc.c | |||
@@ -0,0 +1,85 @@ | |||
1 | /* | ||
2 | * linux/fs/nfs/callback_proc.c | ||
3 | * | ||
4 | * Copyright (C) 2004 Trond Myklebust | ||
5 | * | ||
6 | * NFSv4 callback procedures | ||
7 | */ | ||
8 | #include <linux/config.h> | ||
9 | #include <linux/nfs4.h> | ||
10 | #include <linux/nfs_fs.h> | ||
11 | #include "callback.h" | ||
12 | #include "delegation.h" | ||
13 | |||
14 | #define NFSDBG_FACILITY NFSDBG_CALLBACK | ||
15 | |||
16 | unsigned nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res) | ||
17 | { | ||
18 | struct nfs4_client *clp; | ||
19 | struct nfs_delegation *delegation; | ||
20 | struct nfs_inode *nfsi; | ||
21 | struct inode *inode; | ||
22 | |||
23 | res->bitmap[0] = res->bitmap[1] = 0; | ||
24 | res->status = htonl(NFS4ERR_BADHANDLE); | ||
25 | clp = nfs4_find_client(&args->addr->sin_addr); | ||
26 | if (clp == NULL) | ||
27 | goto out; | ||
28 | inode = nfs_delegation_find_inode(clp, &args->fh); | ||
29 | if (inode == NULL) | ||
30 | goto out_putclient; | ||
31 | nfsi = NFS_I(inode); | ||
32 | down_read(&nfsi->rwsem); | ||
33 | delegation = nfsi->delegation; | ||
34 | if (delegation == NULL || (delegation->type & FMODE_WRITE) == 0) | ||
35 | goto out_iput; | ||
36 | res->size = i_size_read(inode); | ||
37 | res->change_attr = NFS_CHANGE_ATTR(inode); | ||
38 | res->ctime = inode->i_ctime; | ||
39 | res->mtime = inode->i_mtime; | ||
40 | res->bitmap[0] = (FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE) & | ||
41 | args->bitmap[0]; | ||
42 | res->bitmap[1] = (FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY) & | ||
43 | args->bitmap[1]; | ||
44 | res->status = 0; | ||
45 | out_iput: | ||
46 | up_read(&nfsi->rwsem); | ||
47 | iput(inode); | ||
48 | out_putclient: | ||
49 | nfs4_put_client(clp); | ||
50 | out: | ||
51 | dprintk("%s: exit with status = %d\n", __FUNCTION__, ntohl(res->status)); | ||
52 | return res->status; | ||
53 | } | ||
54 | |||
55 | unsigned nfs4_callback_recall(struct cb_recallargs *args, void *dummy) | ||
56 | { | ||
57 | struct nfs4_client *clp; | ||
58 | struct inode *inode; | ||
59 | unsigned res; | ||
60 | |||
61 | res = htonl(NFS4ERR_BADHANDLE); | ||
62 | clp = nfs4_find_client(&args->addr->sin_addr); | ||
63 | if (clp == NULL) | ||
64 | goto out; | ||
65 | inode = nfs_delegation_find_inode(clp, &args->fh); | ||
66 | if (inode == NULL) | ||
67 | goto out_putclient; | ||
68 | /* Set up a helper thread to actually return the delegation */ | ||
69 | switch(nfs_async_inode_return_delegation(inode, &args->stateid)) { | ||
70 | case 0: | ||
71 | res = 0; | ||
72 | break; | ||
73 | case -ENOENT: | ||
74 | res = htonl(NFS4ERR_BAD_STATEID); | ||
75 | break; | ||
76 | default: | ||
77 | res = htonl(NFS4ERR_RESOURCE); | ||
78 | } | ||
79 | iput(inode); | ||
80 | out_putclient: | ||
81 | nfs4_put_client(clp); | ||
82 | out: | ||
83 | dprintk("%s: exit with status = %d\n", __FUNCTION__, ntohl(res)); | ||
84 | return res; | ||
85 | } | ||