aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Layton <jeff.layton@primarydata.com>2017-06-29 09:34:52 -0400
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2017-07-13 16:00:15 -0400
commit5b5faaf6df73412af0278997db36dbcb51011d9d (patch)
tree62c1824135b12d6d393b853c07717c718e8f01b3
parentf174ff7a0ab6a097455a94abfc99517940041c07 (diff)
nfs4: add NFSv4 LOOKUPP handlers
This will be needed in order to implement the get_parent export op for nfsd. Signed-off-by: Jeff Layton <jeff.layton@primarydata.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
-rw-r--r--fs/nfs/nfs4proc.c49
-rw-r--r--fs/nfs/nfs4trace.h29
-rw-r--r--fs/nfs/nfs4xdr.c75
-rw-r--r--include/linux/nfs4.h1
-rw-r--r--include/linux/nfs_xdr.h17
5 files changed, 170 insertions, 1 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 01dcd4c8dc4f..e1a26c653e78 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3805,6 +3805,54 @@ nfs4_proc_lookup_mountpoint(struct inode *dir, const struct qstr *name,
3805 return (client == NFS_CLIENT(dir)) ? rpc_clone_client(client) : client; 3805 return (client == NFS_CLIENT(dir)) ? rpc_clone_client(client) : client;
3806} 3806}
3807 3807
3808static int _nfs4_proc_lookupp(struct inode *inode,
3809 struct nfs_fh *fhandle, struct nfs_fattr *fattr,
3810 struct nfs4_label *label)
3811{
3812 struct rpc_clnt *clnt = NFS_CLIENT(inode);
3813 struct nfs_server *server = NFS_SERVER(inode);
3814 int status;
3815 struct nfs4_lookupp_arg args = {
3816 .bitmask = server->attr_bitmask,
3817 .fh = NFS_FH(inode),
3818 };
3819 struct nfs4_lookupp_res res = {
3820 .server = server,
3821 .fattr = fattr,
3822 .label = label,
3823 .fh = fhandle,
3824 };
3825 struct rpc_message msg = {
3826 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOOKUPP],
3827 .rpc_argp = &args,
3828 .rpc_resp = &res,
3829 };
3830
3831 args.bitmask = nfs4_bitmask(server, label);
3832
3833 nfs_fattr_init(fattr);
3834
3835 dprintk("NFS call lookupp ino=0x%lx\n", inode->i_ino);
3836 status = nfs4_call_sync(clnt, server, &msg, &args.seq_args,
3837 &res.seq_res, 0);
3838 dprintk("NFS reply lookupp: %d\n", status);
3839 return status;
3840}
3841
3842static int nfs4_proc_lookupp(struct inode *inode, struct nfs_fh *fhandle,
3843 struct nfs_fattr *fattr, struct nfs4_label *label)
3844{
3845 struct nfs4_exception exception = { };
3846 int err;
3847 do {
3848 err = _nfs4_proc_lookupp(inode, fhandle, fattr, label);
3849 trace_nfs4_lookupp(inode, err);
3850 err = nfs4_handle_exception(NFS_SERVER(inode), err,
3851 &exception);
3852 } while (exception.retry);
3853 return err;
3854}
3855
3808static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry) 3856static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
3809{ 3857{
3810 struct nfs_server *server = NFS_SERVER(inode); 3858 struct nfs_server *server = NFS_SERVER(inode);
@@ -9314,6 +9362,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
9314 .getattr = nfs4_proc_getattr, 9362 .getattr = nfs4_proc_getattr,
9315 .setattr = nfs4_proc_setattr, 9363 .setattr = nfs4_proc_setattr,
9316 .lookup = nfs4_proc_lookup, 9364 .lookup = nfs4_proc_lookup,
9365 .lookupp = nfs4_proc_lookupp,
9317 .access = nfs4_proc_access, 9366 .access = nfs4_proc_access,
9318 .readlink = nfs4_proc_readlink, 9367 .readlink = nfs4_proc_readlink,
9319 .create = nfs4_proc_create, 9368 .create = nfs4_proc_create,
diff --git a/fs/nfs/nfs4trace.h b/fs/nfs/nfs4trace.h
index 845d0eadefc9..be1da19c65d6 100644
--- a/fs/nfs/nfs4trace.h
+++ b/fs/nfs/nfs4trace.h
@@ -891,6 +891,35 @@ DEFINE_NFS4_LOOKUP_EVENT(nfs4_remove);
891DEFINE_NFS4_LOOKUP_EVENT(nfs4_get_fs_locations); 891DEFINE_NFS4_LOOKUP_EVENT(nfs4_get_fs_locations);
892DEFINE_NFS4_LOOKUP_EVENT(nfs4_secinfo); 892DEFINE_NFS4_LOOKUP_EVENT(nfs4_secinfo);
893 893
894TRACE_EVENT(nfs4_lookupp,
895 TP_PROTO(
896 const struct inode *inode,
897 int error
898 ),
899
900 TP_ARGS(inode, error),
901
902 TP_STRUCT__entry(
903 __field(dev_t, dev)
904 __field(u64, ino)
905 __field(int, error)
906 ),
907
908 TP_fast_assign(
909 __entry->dev = inode->i_sb->s_dev;
910 __entry->ino = NFS_FILEID(inode);
911 __entry->error = error;
912 ),
913
914 TP_printk(
915 "error=%d (%s) inode=%02x:%02x:%llu",
916 __entry->error,
917 show_nfsv4_errors(__entry->error),
918 MAJOR(__entry->dev), MINOR(__entry->dev),
919 (unsigned long long)__entry->ino
920 )
921);
922
894TRACE_EVENT(nfs4_rename, 923TRACE_EVENT(nfs4_rename,
895 TP_PROTO( 924 TP_PROTO(
896 const struct inode *olddir, 925 const struct inode *olddir,
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 495d493d3a35..fa3eb361d4f8 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -159,6 +159,8 @@ static int nfs4_stat_to_errno(int);
159 (op_decode_hdr_maxsz) 159 (op_decode_hdr_maxsz)
160#define encode_lookup_maxsz (op_encode_hdr_maxsz + nfs4_name_maxsz) 160#define encode_lookup_maxsz (op_encode_hdr_maxsz + nfs4_name_maxsz)
161#define decode_lookup_maxsz (op_decode_hdr_maxsz) 161#define decode_lookup_maxsz (op_decode_hdr_maxsz)
162#define encode_lookupp_maxsz (op_encode_hdr_maxsz)
163#define decode_lookupp_maxsz (op_decode_hdr_maxsz)
162#define encode_share_access_maxsz \ 164#define encode_share_access_maxsz \
163 (2) 165 (2)
164#define encode_createmode_maxsz (1 + encode_attrs_maxsz + encode_verifier_maxsz) 166#define encode_createmode_maxsz (1 + encode_attrs_maxsz + encode_verifier_maxsz)
@@ -618,6 +620,18 @@ static int nfs4_stat_to_errno(int);
618 decode_lookup_maxsz + \ 620 decode_lookup_maxsz + \
619 decode_getattr_maxsz + \ 621 decode_getattr_maxsz + \
620 decode_getfh_maxsz) 622 decode_getfh_maxsz)
623#define NFS4_enc_lookupp_sz (compound_encode_hdr_maxsz + \
624 encode_sequence_maxsz + \
625 encode_putfh_maxsz + \
626 encode_lookupp_maxsz + \
627 encode_getattr_maxsz + \
628 encode_getfh_maxsz)
629#define NFS4_dec_lookupp_sz (compound_decode_hdr_maxsz + \
630 decode_sequence_maxsz + \
631 decode_putfh_maxsz + \
632 decode_lookupp_maxsz + \
633 decode_getattr_maxsz + \
634 decode_getfh_maxsz)
621#define NFS4_enc_lookup_root_sz (compound_encode_hdr_maxsz + \ 635#define NFS4_enc_lookup_root_sz (compound_encode_hdr_maxsz + \
622 encode_sequence_maxsz + \ 636 encode_sequence_maxsz + \
623 encode_putrootfh_maxsz + \ 637 encode_putrootfh_maxsz + \
@@ -1368,6 +1382,11 @@ static void encode_lookup(struct xdr_stream *xdr, const struct qstr *name, struc
1368 encode_string(xdr, name->len, name->name); 1382 encode_string(xdr, name->len, name->name);
1369} 1383}
1370 1384
1385static void encode_lookupp(struct xdr_stream *xdr, struct compound_hdr *hdr)
1386{
1387 encode_op_hdr(xdr, OP_LOOKUPP, decode_lookupp_maxsz, hdr);
1388}
1389
1371static void encode_share_access(struct xdr_stream *xdr, u32 share_access) 1390static void encode_share_access(struct xdr_stream *xdr, u32 share_access)
1372{ 1391{
1373 __be32 *p; 1392 __be32 *p;
@@ -2123,6 +2142,26 @@ static void nfs4_xdr_enc_lookup(struct rpc_rqst *req, struct xdr_stream *xdr,
2123} 2142}
2124 2143
2125/* 2144/*
2145 * Encode LOOKUPP request
2146 */
2147static void nfs4_xdr_enc_lookupp(struct rpc_rqst *req, struct xdr_stream *xdr,
2148 const void *data)
2149{
2150 const struct nfs4_lookupp_arg *args = data;
2151 struct compound_hdr hdr = {
2152 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
2153 };
2154
2155 encode_compound_hdr(xdr, req, &hdr);
2156 encode_sequence(xdr, &args->seq_args, &hdr);
2157 encode_putfh(xdr, args->fh, &hdr);
2158 encode_lookupp(xdr, &hdr);
2159 encode_getfh(xdr, &hdr);
2160 encode_getfattr(xdr, args->bitmask, &hdr);
2161 encode_nops(&hdr);
2162}
2163
2164/*
2126 * Encode LOOKUP_ROOT request 2165 * Encode LOOKUP_ROOT request
2127 */ 2166 */
2128static void nfs4_xdr_enc_lookup_root(struct rpc_rqst *req, 2167static void nfs4_xdr_enc_lookup_root(struct rpc_rqst *req,
@@ -5058,6 +5097,11 @@ static int decode_lookup(struct xdr_stream *xdr)
5058 return decode_op_hdr(xdr, OP_LOOKUP); 5097 return decode_op_hdr(xdr, OP_LOOKUP);
5059} 5098}
5060 5099
5100static int decode_lookupp(struct xdr_stream *xdr)
5101{
5102 return decode_op_hdr(xdr, OP_LOOKUPP);
5103}
5104
5061/* This is too sick! */ 5105/* This is too sick! */
5062static int decode_space_limit(struct xdr_stream *xdr, 5106static int decode_space_limit(struct xdr_stream *xdr,
5063 unsigned long *pagemod_limit) 5107 unsigned long *pagemod_limit)
@@ -6238,6 +6282,36 @@ out:
6238} 6282}
6239 6283
6240/* 6284/*
6285 * Decode LOOKUPP response
6286 */
6287static int nfs4_xdr_dec_lookupp(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
6288 void *data)
6289{
6290 struct nfs4_lookupp_res *res = data;
6291 struct compound_hdr hdr;
6292 int status;
6293
6294 status = decode_compound_hdr(xdr, &hdr);
6295 if (status)
6296 goto out;
6297 status = decode_sequence(xdr, &res->seq_res, rqstp);
6298 if (status)
6299 goto out;
6300 status = decode_putfh(xdr);
6301 if (status)
6302 goto out;
6303 status = decode_lookupp(xdr);
6304 if (status)
6305 goto out;
6306 status = decode_getfh(xdr, res->fh);
6307 if (status)
6308 goto out;
6309 status = decode_getfattr_label(xdr, res->fattr, res->label, res->server);
6310out:
6311 return status;
6312}
6313
6314/*
6241 * Decode LOOKUP_ROOT response 6315 * Decode LOOKUP_ROOT response
6242 */ 6316 */
6243static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp, 6317static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp,
@@ -7614,6 +7688,7 @@ const struct rpc_procinfo nfs4_procedures[] = {
7614 PROC(ACCESS, enc_access, dec_access), 7688 PROC(ACCESS, enc_access, dec_access),
7615 PROC(GETATTR, enc_getattr, dec_getattr), 7689 PROC(GETATTR, enc_getattr, dec_getattr),
7616 PROC(LOOKUP, enc_lookup, dec_lookup), 7690 PROC(LOOKUP, enc_lookup, dec_lookup),
7691 PROC(LOOKUPP, enc_lookupp, dec_lookupp),
7617 PROC(LOOKUP_ROOT, enc_lookup_root, dec_lookup_root), 7692 PROC(LOOKUP_ROOT, enc_lookup_root, dec_lookup_root),
7618 PROC(REMOVE, enc_remove, dec_remove), 7693 PROC(REMOVE, enc_remove, dec_remove),
7619 PROC(RENAME, enc_rename, dec_rename), 7694 PROC(RENAME, enc_rename, dec_rename),
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index 1b1ca04820a3..47239c336688 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -479,6 +479,7 @@ enum {
479 NFSPROC4_CLNT_ACCESS, 479 NFSPROC4_CLNT_ACCESS,
480 NFSPROC4_CLNT_GETATTR, 480 NFSPROC4_CLNT_GETATTR,
481 NFSPROC4_CLNT_LOOKUP, 481 NFSPROC4_CLNT_LOOKUP,
482 NFSPROC4_CLNT_LOOKUPP,
482 NFSPROC4_CLNT_LOOKUP_ROOT, 483 NFSPROC4_CLNT_LOOKUP_ROOT,
483 NFSPROC4_CLNT_REMOVE, 484 NFSPROC4_CLNT_REMOVE,
484 NFSPROC4_CLNT_RENAME, 485 NFSPROC4_CLNT_RENAME,
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 89093341f076..ca3bcc4ed4e5 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -1012,7 +1012,6 @@ struct nfs4_link_res {
1012 struct nfs_fattr * dir_attr; 1012 struct nfs_fattr * dir_attr;
1013}; 1013};
1014 1014
1015
1016struct nfs4_lookup_arg { 1015struct nfs4_lookup_arg {
1017 struct nfs4_sequence_args seq_args; 1016 struct nfs4_sequence_args seq_args;
1018 const struct nfs_fh * dir_fh; 1017 const struct nfs_fh * dir_fh;
@@ -1028,6 +1027,20 @@ struct nfs4_lookup_res {
1028 struct nfs4_label *label; 1027 struct nfs4_label *label;
1029}; 1028};
1030 1029
1030struct nfs4_lookupp_arg {
1031 struct nfs4_sequence_args seq_args;
1032 const struct nfs_fh *fh;
1033 const u32 *bitmask;
1034};
1035
1036struct nfs4_lookupp_res {
1037 struct nfs4_sequence_res seq_res;
1038 const struct nfs_server *server;
1039 struct nfs_fattr *fattr;
1040 struct nfs_fh *fh;
1041 struct nfs4_label *label;
1042};
1043
1031struct nfs4_lookup_root_arg { 1044struct nfs4_lookup_root_arg {
1032 struct nfs4_sequence_args seq_args; 1045 struct nfs4_sequence_args seq_args;
1033 const u32 * bitmask; 1046 const u32 * bitmask;
@@ -1569,6 +1582,8 @@ struct nfs_rpc_ops {
1569 int (*lookup) (struct inode *, const struct qstr *, 1582 int (*lookup) (struct inode *, const struct qstr *,
1570 struct nfs_fh *, struct nfs_fattr *, 1583 struct nfs_fh *, struct nfs_fattr *,
1571 struct nfs4_label *); 1584 struct nfs4_label *);
1585 int (*lookupp) (struct inode *, struct nfs_fh *,
1586 struct nfs_fattr *, struct nfs4_label *);
1572 int (*access) (struct inode *, struct nfs_access_entry *); 1587 int (*access) (struct inode *, struct nfs_access_entry *);
1573 int (*readlink)(struct inode *, struct page *, unsigned int, 1588 int (*readlink)(struct inode *, struct page *, unsigned int,
1574 unsigned int); 1589 unsigned int);