2 * Copyright (c) 2014 Anna Schumaker <Anna.Schumaker@Netapp.com>
5 #include <linux/sunrpc/sched.h>
7 #include <linux/nfs3.h>
8 #include <linux/nfs4.h>
9 #include <linux/nfs_xdr.h>
10 #include <linux/nfs_fs.h>
14 static int nfs42_set_rw_stateid(nfs4_stateid
*dst
, struct file
*file
,
17 struct nfs_open_context
*open
;
18 struct nfs_lock_context
*lock
;
21 open
= get_nfs_open_context(nfs_file_open_context(file
));
22 lock
= nfs_get_lock_context(open
);
24 put_nfs_open_context(open
);
28 ret
= nfs4_set_rw_stateid(dst
, open
, lock
, fmode
);
30 nfs_put_lock_context(lock
);
31 put_nfs_open_context(open
);
35 loff_t
nfs42_proc_llseek(struct file
*filep
, loff_t offset
, int whence
)
37 struct inode
*inode
= file_inode(filep
);
38 struct nfs42_seek_args args
= {
39 .sa_fh
= NFS_FH(inode
),
41 .sa_what
= (whence
== SEEK_HOLE
) ?
42 NFS4_CONTENT_HOLE
: NFS4_CONTENT_DATA
,
44 struct nfs42_seek_res res
;
45 struct rpc_message msg
= {
46 .rpc_proc
= &nfs4_procedures
[NFSPROC4_CLNT_SEEK
],
50 struct nfs_server
*server
= NFS_SERVER(inode
);
53 if (!(server
->caps
& NFS_CAP_SEEK
))
56 status
= nfs42_set_rw_stateid(&args
.sa_stateid
, filep
, FMODE_READ
);
61 status
= nfs4_call_sync(server
->client
, server
, &msg
,
62 &args
.seq_args
, &res
.seq_res
, 0);
63 if (status
== -ENOTSUPP
)
64 server
->caps
&= ~NFS_CAP_SEEK
;
68 return vfs_setpos(filep
, res
.sr_offset
, inode
->i_sb
->s_maxbytes
);