mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 04:31:50 +00:00
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>
This commit is contained in:
parent
f174ff7a0a
commit
5b5faaf6df
@ -3805,6 +3805,54 @@ nfs4_proc_lookup_mountpoint(struct inode *dir, const struct qstr *name,
|
||||
return (client == NFS_CLIENT(dir)) ? rpc_clone_client(client) : client;
|
||||
}
|
||||
|
||||
static int _nfs4_proc_lookupp(struct inode *inode,
|
||||
struct nfs_fh *fhandle, struct nfs_fattr *fattr,
|
||||
struct nfs4_label *label)
|
||||
{
|
||||
struct rpc_clnt *clnt = NFS_CLIENT(inode);
|
||||
struct nfs_server *server = NFS_SERVER(inode);
|
||||
int status;
|
||||
struct nfs4_lookupp_arg args = {
|
||||
.bitmask = server->attr_bitmask,
|
||||
.fh = NFS_FH(inode),
|
||||
};
|
||||
struct nfs4_lookupp_res res = {
|
||||
.server = server,
|
||||
.fattr = fattr,
|
||||
.label = label,
|
||||
.fh = fhandle,
|
||||
};
|
||||
struct rpc_message msg = {
|
||||
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOOKUPP],
|
||||
.rpc_argp = &args,
|
||||
.rpc_resp = &res,
|
||||
};
|
||||
|
||||
args.bitmask = nfs4_bitmask(server, label);
|
||||
|
||||
nfs_fattr_init(fattr);
|
||||
|
||||
dprintk("NFS call lookupp ino=0x%lx\n", inode->i_ino);
|
||||
status = nfs4_call_sync(clnt, server, &msg, &args.seq_args,
|
||||
&res.seq_res, 0);
|
||||
dprintk("NFS reply lookupp: %d\n", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int nfs4_proc_lookupp(struct inode *inode, struct nfs_fh *fhandle,
|
||||
struct nfs_fattr *fattr, struct nfs4_label *label)
|
||||
{
|
||||
struct nfs4_exception exception = { };
|
||||
int err;
|
||||
do {
|
||||
err = _nfs4_proc_lookupp(inode, fhandle, fattr, label);
|
||||
trace_nfs4_lookupp(inode, err);
|
||||
err = nfs4_handle_exception(NFS_SERVER(inode), err,
|
||||
&exception);
|
||||
} while (exception.retry);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
|
||||
{
|
||||
struct nfs_server *server = NFS_SERVER(inode);
|
||||
@ -9314,6 +9362,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
|
||||
.getattr = nfs4_proc_getattr,
|
||||
.setattr = nfs4_proc_setattr,
|
||||
.lookup = nfs4_proc_lookup,
|
||||
.lookupp = nfs4_proc_lookupp,
|
||||
.access = nfs4_proc_access,
|
||||
.readlink = nfs4_proc_readlink,
|
||||
.create = nfs4_proc_create,
|
||||
|
@ -891,6 +891,35 @@ DEFINE_NFS4_LOOKUP_EVENT(nfs4_remove);
|
||||
DEFINE_NFS4_LOOKUP_EVENT(nfs4_get_fs_locations);
|
||||
DEFINE_NFS4_LOOKUP_EVENT(nfs4_secinfo);
|
||||
|
||||
TRACE_EVENT(nfs4_lookupp,
|
||||
TP_PROTO(
|
||||
const struct inode *inode,
|
||||
int error
|
||||
),
|
||||
|
||||
TP_ARGS(inode, error),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(dev_t, dev)
|
||||
__field(u64, ino)
|
||||
__field(int, error)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->dev = inode->i_sb->s_dev;
|
||||
__entry->ino = NFS_FILEID(inode);
|
||||
__entry->error = error;
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
"error=%d (%s) inode=%02x:%02x:%llu",
|
||||
__entry->error,
|
||||
show_nfsv4_errors(__entry->error),
|
||||
MAJOR(__entry->dev), MINOR(__entry->dev),
|
||||
(unsigned long long)__entry->ino
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(nfs4_rename,
|
||||
TP_PROTO(
|
||||
const struct inode *olddir,
|
||||
|
@ -159,6 +159,8 @@ static int nfs4_stat_to_errno(int);
|
||||
(op_decode_hdr_maxsz)
|
||||
#define encode_lookup_maxsz (op_encode_hdr_maxsz + nfs4_name_maxsz)
|
||||
#define decode_lookup_maxsz (op_decode_hdr_maxsz)
|
||||
#define encode_lookupp_maxsz (op_encode_hdr_maxsz)
|
||||
#define decode_lookupp_maxsz (op_decode_hdr_maxsz)
|
||||
#define encode_share_access_maxsz \
|
||||
(2)
|
||||
#define encode_createmode_maxsz (1 + encode_attrs_maxsz + encode_verifier_maxsz)
|
||||
@ -618,6 +620,18 @@ static int nfs4_stat_to_errno(int);
|
||||
decode_lookup_maxsz + \
|
||||
decode_getattr_maxsz + \
|
||||
decode_getfh_maxsz)
|
||||
#define NFS4_enc_lookupp_sz (compound_encode_hdr_maxsz + \
|
||||
encode_sequence_maxsz + \
|
||||
encode_putfh_maxsz + \
|
||||
encode_lookupp_maxsz + \
|
||||
encode_getattr_maxsz + \
|
||||
encode_getfh_maxsz)
|
||||
#define NFS4_dec_lookupp_sz (compound_decode_hdr_maxsz + \
|
||||
decode_sequence_maxsz + \
|
||||
decode_putfh_maxsz + \
|
||||
decode_lookupp_maxsz + \
|
||||
decode_getattr_maxsz + \
|
||||
decode_getfh_maxsz)
|
||||
#define NFS4_enc_lookup_root_sz (compound_encode_hdr_maxsz + \
|
||||
encode_sequence_maxsz + \
|
||||
encode_putrootfh_maxsz + \
|
||||
@ -1368,6 +1382,11 @@ static void encode_lookup(struct xdr_stream *xdr, const struct qstr *name, struc
|
||||
encode_string(xdr, name->len, name->name);
|
||||
}
|
||||
|
||||
static void encode_lookupp(struct xdr_stream *xdr, struct compound_hdr *hdr)
|
||||
{
|
||||
encode_op_hdr(xdr, OP_LOOKUPP, decode_lookupp_maxsz, hdr);
|
||||
}
|
||||
|
||||
static void encode_share_access(struct xdr_stream *xdr, u32 share_access)
|
||||
{
|
||||
__be32 *p;
|
||||
@ -2122,6 +2141,26 @@ static void nfs4_xdr_enc_lookup(struct rpc_rqst *req, struct xdr_stream *xdr,
|
||||
encode_nops(&hdr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Encode LOOKUPP request
|
||||
*/
|
||||
static void nfs4_xdr_enc_lookupp(struct rpc_rqst *req, struct xdr_stream *xdr,
|
||||
const void *data)
|
||||
{
|
||||
const struct nfs4_lookupp_arg *args = data;
|
||||
struct compound_hdr hdr = {
|
||||
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
|
||||
};
|
||||
|
||||
encode_compound_hdr(xdr, req, &hdr);
|
||||
encode_sequence(xdr, &args->seq_args, &hdr);
|
||||
encode_putfh(xdr, args->fh, &hdr);
|
||||
encode_lookupp(xdr, &hdr);
|
||||
encode_getfh(xdr, &hdr);
|
||||
encode_getfattr(xdr, args->bitmask, &hdr);
|
||||
encode_nops(&hdr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Encode LOOKUP_ROOT request
|
||||
*/
|
||||
@ -5058,6 +5097,11 @@ static int decode_lookup(struct xdr_stream *xdr)
|
||||
return decode_op_hdr(xdr, OP_LOOKUP);
|
||||
}
|
||||
|
||||
static int decode_lookupp(struct xdr_stream *xdr)
|
||||
{
|
||||
return decode_op_hdr(xdr, OP_LOOKUPP);
|
||||
}
|
||||
|
||||
/* This is too sick! */
|
||||
static int decode_space_limit(struct xdr_stream *xdr,
|
||||
unsigned long *pagemod_limit)
|
||||
@ -6237,6 +6281,36 @@ out:
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode LOOKUPP response
|
||||
*/
|
||||
static int nfs4_xdr_dec_lookupp(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
|
||||
void *data)
|
||||
{
|
||||
struct nfs4_lookupp_res *res = data;
|
||||
struct compound_hdr hdr;
|
||||
int status;
|
||||
|
||||
status = decode_compound_hdr(xdr, &hdr);
|
||||
if (status)
|
||||
goto out;
|
||||
status = decode_sequence(xdr, &res->seq_res, rqstp);
|
||||
if (status)
|
||||
goto out;
|
||||
status = decode_putfh(xdr);
|
||||
if (status)
|
||||
goto out;
|
||||
status = decode_lookupp(xdr);
|
||||
if (status)
|
||||
goto out;
|
||||
status = decode_getfh(xdr, res->fh);
|
||||
if (status)
|
||||
goto out;
|
||||
status = decode_getfattr_label(xdr, res->fattr, res->label, res->server);
|
||||
out:
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode LOOKUP_ROOT response
|
||||
*/
|
||||
@ -7614,6 +7688,7 @@ const struct rpc_procinfo nfs4_procedures[] = {
|
||||
PROC(ACCESS, enc_access, dec_access),
|
||||
PROC(GETATTR, enc_getattr, dec_getattr),
|
||||
PROC(LOOKUP, enc_lookup, dec_lookup),
|
||||
PROC(LOOKUPP, enc_lookupp, dec_lookupp),
|
||||
PROC(LOOKUP_ROOT, enc_lookup_root, dec_lookup_root),
|
||||
PROC(REMOVE, enc_remove, dec_remove),
|
||||
PROC(RENAME, enc_rename, dec_rename),
|
||||
|
@ -479,6 +479,7 @@ enum {
|
||||
NFSPROC4_CLNT_ACCESS,
|
||||
NFSPROC4_CLNT_GETATTR,
|
||||
NFSPROC4_CLNT_LOOKUP,
|
||||
NFSPROC4_CLNT_LOOKUPP,
|
||||
NFSPROC4_CLNT_LOOKUP_ROOT,
|
||||
NFSPROC4_CLNT_REMOVE,
|
||||
NFSPROC4_CLNT_RENAME,
|
||||
|
@ -1012,7 +1012,6 @@ struct nfs4_link_res {
|
||||
struct nfs_fattr * dir_attr;
|
||||
};
|
||||
|
||||
|
||||
struct nfs4_lookup_arg {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
const struct nfs_fh * dir_fh;
|
||||
@ -1028,6 +1027,20 @@ struct nfs4_lookup_res {
|
||||
struct nfs4_label *label;
|
||||
};
|
||||
|
||||
struct nfs4_lookupp_arg {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
const struct nfs_fh *fh;
|
||||
const u32 *bitmask;
|
||||
};
|
||||
|
||||
struct nfs4_lookupp_res {
|
||||
struct nfs4_sequence_res seq_res;
|
||||
const struct nfs_server *server;
|
||||
struct nfs_fattr *fattr;
|
||||
struct nfs_fh *fh;
|
||||
struct nfs4_label *label;
|
||||
};
|
||||
|
||||
struct nfs4_lookup_root_arg {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
const u32 * bitmask;
|
||||
@ -1569,6 +1582,8 @@ struct nfs_rpc_ops {
|
||||
int (*lookup) (struct inode *, const struct qstr *,
|
||||
struct nfs_fh *, struct nfs_fattr *,
|
||||
struct nfs4_label *);
|
||||
int (*lookupp) (struct inode *, struct nfs_fh *,
|
||||
struct nfs_fattr *, struct nfs4_label *);
|
||||
int (*access) (struct inode *, struct nfs_access_entry *);
|
||||
int (*readlink)(struct inode *, struct page *, unsigned int,
|
||||
unsigned int);
|
||||
|
Loading…
Reference in New Issue
Block a user