mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 03:01:39 -04:00
Merge branch 'for-3.15' of git://linux-nfs.org/~bfields/linux
Pull nfsd updates from Bruce Fields:
"Highlights:
- server-side nfs/rdma fixes from Jeff Layton and Tom Tucker
- xdr fixes (a larger xdr rewrite has been posted but I decided it
would be better to queue it up for 3.16).
- miscellaneous fixes and cleanup from all over (thanks especially to
Kinglong Mee)"
* 'for-3.15' of git://linux-nfs.org/~bfields/linux: (36 commits)
nfsd4: don't create unnecessary mask acl
nfsd: revert v2 half of "nfsd: don't return high mode bits"
nfsd4: fix memory leak in nfsd4_encode_fattr()
nfsd: check passed socket's net matches NFSd superblock's one
SUNRPC: Clear xpt_bc_xprt if xs_setup_bc_tcp failed
NFSD/SUNRPC: Check rpc_xprt out of xs_setup_bc_tcp
SUNRPC: New helper for creating client with rpc_xprt
NFSD: Free backchannel xprt in bc_destroy
NFSD: Clear wcc data between compound ops
nfsd: Don't return NFS4ERR_STALE_STATEID for NFSv4.1+
nfsd4: fix nfs4err_resource in 4.1 case
nfsd4: fix setclientid encode size
nfsd4: remove redundant check from nfsd4_check_resp_size
nfsd4: use more generous NFS4_ACL_MAX
nfsd4: minor nfsd4_replay_cache_entry cleanup
nfsd4: nfsd4_replay_cache_entry should be static
nfsd4: update comments with obsolete function name
rpc: Allow xdr_buf_subsegment to operate in-place
NFSD: Using free_conn free connection
SUNRPC: fix memory leak of peer addresses in XPRT
...
This commit is contained in:
commit
75ff24fa52
27 changed files with 264 additions and 137 deletions
|
|
@ -39,9 +39,13 @@ struct nfs4_acl;
|
|||
struct svc_fh;
|
||||
struct svc_rqst;
|
||||
|
||||
/* Maximum ACL we'll accept from client; chosen (somewhat arbitrarily) to
|
||||
* fit in a page: */
|
||||
#define NFS4_ACL_MAX 170
|
||||
/*
|
||||
* Maximum ACL we'll accept from a client; chosen (somewhat
|
||||
* arbitrarily) so that kmalloc'ing the ACL shouldn't require a
|
||||
* high-order allocation. This allows 204 ACEs on x86_64:
|
||||
*/
|
||||
#define NFS4_ACL_MAX ((PAGE_SIZE - sizeof(struct nfs4_acl)) \
|
||||
/ sizeof(struct nfs4_ace))
|
||||
|
||||
struct nfs4_acl *nfs4_acl_new(int);
|
||||
int nfs4_acl_get_whotype(char *, u32);
|
||||
|
|
|
|||
|
|
@ -542,7 +542,10 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
|
|||
* up setting a 3-element effective posix ACL with all
|
||||
* permissions zero.
|
||||
*/
|
||||
nace = 4 + state->users->n + state->groups->n;
|
||||
if (!state->users->n && !state->groups->n)
|
||||
nace = 3;
|
||||
else /* Note we also include a MASK ACE in this case: */
|
||||
nace = 4 + state->users->n + state->groups->n;
|
||||
pacl = posix_acl_alloc(nace, GFP_KERNEL);
|
||||
if (!pacl)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
|
@ -586,9 +589,11 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
|
|||
add_to_mask(state, &state->groups->aces[i].perms);
|
||||
}
|
||||
|
||||
pace++;
|
||||
pace->e_tag = ACL_MASK;
|
||||
low_mode_from_nfs4(state->mask.allow, &pace->e_perm, flags);
|
||||
if (!state->users->n && !state->groups->n) {
|
||||
pace++;
|
||||
pace->e_tag = ACL_MASK;
|
||||
low_mode_from_nfs4(state->mask.allow, &pace->e_perm, flags);
|
||||
}
|
||||
|
||||
pace++;
|
||||
pace->e_tag = ACL_OTHER;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/sunrpc/clnt.h>
|
||||
#include <linux/sunrpc/xprt.h>
|
||||
#include <linux/sunrpc/svc_xprt.h>
|
||||
#include <linux/slab.h>
|
||||
#include "nfsd.h"
|
||||
|
|
@ -635,6 +636,22 @@ static struct rpc_cred *get_backchannel_cred(struct nfs4_client *clp, struct rpc
|
|||
}
|
||||
}
|
||||
|
||||
static struct rpc_clnt *create_backchannel_client(struct rpc_create_args *args)
|
||||
{
|
||||
struct rpc_xprt *xprt;
|
||||
|
||||
if (args->protocol != XPRT_TRANSPORT_BC_TCP)
|
||||
return rpc_create(args);
|
||||
|
||||
xprt = args->bc_xprt->xpt_bc_xprt;
|
||||
if (xprt) {
|
||||
xprt_get(xprt);
|
||||
return rpc_create_xprt(args, xprt);
|
||||
}
|
||||
|
||||
return rpc_create(args);
|
||||
}
|
||||
|
||||
static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn, struct nfsd4_session *ses)
|
||||
{
|
||||
struct rpc_timeout timeparms = {
|
||||
|
|
@ -674,7 +691,7 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
|
|||
args.authflavor = ses->se_cb_sec.flavor;
|
||||
}
|
||||
/* Create RPC client */
|
||||
client = rpc_create(&args);
|
||||
client = create_backchannel_client(&args);
|
||||
if (IS_ERR(client)) {
|
||||
dprintk("NFSD: couldn't create callback client: %ld\n",
|
||||
PTR_ERR(client));
|
||||
|
|
|
|||
|
|
@ -1273,6 +1273,8 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
|
|||
struct nfsd4_op *op;
|
||||
struct nfsd4_operation *opdesc;
|
||||
struct nfsd4_compound_state *cstate = &resp->cstate;
|
||||
struct svc_fh *current_fh = &cstate->current_fh;
|
||||
struct svc_fh *save_fh = &cstate->save_fh;
|
||||
int slack_bytes;
|
||||
u32 plen = 0;
|
||||
__be32 status;
|
||||
|
|
@ -1288,11 +1290,11 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
|
|||
resp->tag = args->tag;
|
||||
resp->opcnt = 0;
|
||||
resp->rqstp = rqstp;
|
||||
resp->cstate.minorversion = args->minorversion;
|
||||
resp->cstate.replay_owner = NULL;
|
||||
resp->cstate.session = NULL;
|
||||
fh_init(&resp->cstate.current_fh, NFS4_FHSIZE);
|
||||
fh_init(&resp->cstate.save_fh, NFS4_FHSIZE);
|
||||
cstate->minorversion = args->minorversion;
|
||||
cstate->replay_owner = NULL;
|
||||
cstate->session = NULL;
|
||||
fh_init(current_fh, NFS4_FHSIZE);
|
||||
fh_init(save_fh, NFS4_FHSIZE);
|
||||
/*
|
||||
* Don't use the deferral mechanism for NFSv4; compounds make it
|
||||
* too hard to avoid non-idempotency problems.
|
||||
|
|
@ -1345,20 +1347,28 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
|
|||
|
||||
opdesc = OPDESC(op);
|
||||
|
||||
if (!cstate->current_fh.fh_dentry) {
|
||||
if (!current_fh->fh_dentry) {
|
||||
if (!(opdesc->op_flags & ALLOWED_WITHOUT_FH)) {
|
||||
op->status = nfserr_nofilehandle;
|
||||
goto encode_op;
|
||||
}
|
||||
} else if (cstate->current_fh.fh_export->ex_fslocs.migrated &&
|
||||
} else if (current_fh->fh_export->ex_fslocs.migrated &&
|
||||
!(opdesc->op_flags & ALLOWED_ON_ABSENT_FS)) {
|
||||
op->status = nfserr_moved;
|
||||
goto encode_op;
|
||||
}
|
||||
|
||||
fh_clear_wcc(current_fh);
|
||||
|
||||
/* If op is non-idempotent */
|
||||
if (opdesc->op_flags & OP_MODIFIES_SOMETHING) {
|
||||
plen = opdesc->op_rsize_bop(rqstp, op);
|
||||
/*
|
||||
* If there's still another operation, make sure
|
||||
* we'll have space to at least encode an error:
|
||||
*/
|
||||
if (resp->opcnt < args->opcnt)
|
||||
plen += COMPOUND_ERR_SLACK_SPACE;
|
||||
op->status = nfsd4_check_resp_size(resp, plen);
|
||||
}
|
||||
|
||||
|
|
@ -1377,12 +1387,12 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
|
|||
clear_current_stateid(cstate);
|
||||
|
||||
if (need_wrongsec_check(rqstp))
|
||||
op->status = check_nfsd_access(cstate->current_fh.fh_export, rqstp);
|
||||
op->status = check_nfsd_access(current_fh->fh_export, rqstp);
|
||||
}
|
||||
|
||||
encode_op:
|
||||
/* Only from SEQUENCE */
|
||||
if (resp->cstate.status == nfserr_replay_cache) {
|
||||
if (cstate->status == nfserr_replay_cache) {
|
||||
dprintk("%s NFS4.1 replay from cache\n", __func__);
|
||||
status = op->status;
|
||||
goto out;
|
||||
|
|
@ -1411,10 +1421,10 @@ encode_op:
|
|||
nfsd4_increment_op_stats(op->opnum);
|
||||
}
|
||||
|
||||
resp->cstate.status = status;
|
||||
fh_put(&resp->cstate.current_fh);
|
||||
fh_put(&resp->cstate.save_fh);
|
||||
BUG_ON(resp->cstate.replay_owner);
|
||||
cstate->status = status;
|
||||
fh_put(current_fh);
|
||||
fh_put(save_fh);
|
||||
BUG_ON(cstate->replay_owner);
|
||||
out:
|
||||
/* Reset deferral mechanism for RPC deferrals */
|
||||
rqstp->rq_usedeferral = 1;
|
||||
|
|
@ -1523,7 +1533,8 @@ static inline u32 nfsd4_setattr_rsize(struct svc_rqst *rqstp, struct nfsd4_op *o
|
|||
|
||||
static inline u32 nfsd4_setclientid_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
|
||||
{
|
||||
return (op_encode_hdr_size + 2 + 1024) * sizeof(__be32);
|
||||
return (op_encode_hdr_size + 2 + XDR_QUADLEN(NFS4_VERIFIER_SIZE)) *
|
||||
sizeof(__be32);
|
||||
}
|
||||
|
||||
static inline u32 nfsd4_write_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
|
||||
|
|
|
|||
|
|
@ -1538,7 +1538,7 @@ out_err:
|
|||
}
|
||||
|
||||
/*
|
||||
* Cache a reply. nfsd4_check_drc_limit() has bounded the cache size.
|
||||
* Cache a reply. nfsd4_check_resp_size() has bounded the cache size.
|
||||
*/
|
||||
void
|
||||
nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
|
||||
|
|
@ -1596,7 +1596,7 @@ nfsd4_enc_sequence_replay(struct nfsd4_compoundargs *args,
|
|||
* The sequence operation is not cached because we can use the slot and
|
||||
* session values.
|
||||
*/
|
||||
__be32
|
||||
static __be32
|
||||
nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
|
||||
struct nfsd4_sequence *seq)
|
||||
{
|
||||
|
|
@ -1605,9 +1605,8 @@ nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
|
|||
|
||||
dprintk("--> %s slot %p\n", __func__, slot);
|
||||
|
||||
/* Either returns 0 or nfserr_retry_uncached */
|
||||
status = nfsd4_enc_sequence_replay(resp->rqstp->rq_argp, resp);
|
||||
if (status == nfserr_retry_uncached_rep)
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* The sequence operation has been encoded, cstate->datap set. */
|
||||
|
|
@ -2287,7 +2286,8 @@ out:
|
|||
if (!list_empty(&clp->cl_revoked))
|
||||
seq->status_flags |= SEQ4_STATUS_RECALLABLE_STATE_REVOKED;
|
||||
out_no_session:
|
||||
kfree(conn);
|
||||
if (conn)
|
||||
free_conn(conn);
|
||||
spin_unlock(&nn->client_lock);
|
||||
return status;
|
||||
out_put_session:
|
||||
|
|
@ -3627,8 +3627,11 @@ static __be32 nfsd4_lookup_stateid(stateid_t *stateid, unsigned char typemask,
|
|||
return nfserr_bad_stateid;
|
||||
status = lookup_clientid(&stateid->si_opaque.so_clid, sessions,
|
||||
nn, &cl);
|
||||
if (status == nfserr_stale_clientid)
|
||||
if (status == nfserr_stale_clientid) {
|
||||
if (sessions)
|
||||
return nfserr_bad_stateid;
|
||||
return nfserr_stale_stateid;
|
||||
}
|
||||
if (status)
|
||||
return status;
|
||||
*s = find_stateid_by_type(cl, stateid, typemask);
|
||||
|
|
@ -5062,7 +5065,6 @@ nfs4_state_destroy_net(struct net *net)
|
|||
int i;
|
||||
struct nfs4_client *clp = NULL;
|
||||
struct nfsd_net *nn = net_generic(net, nfsd_net_id);
|
||||
struct rb_node *node, *tmp;
|
||||
|
||||
for (i = 0; i < CLIENT_HASH_SIZE; i++) {
|
||||
while (!list_empty(&nn->conf_id_hashtbl[i])) {
|
||||
|
|
@ -5071,13 +5073,11 @@ nfs4_state_destroy_net(struct net *net)
|
|||
}
|
||||
}
|
||||
|
||||
node = rb_first(&nn->unconf_name_tree);
|
||||
while (node != NULL) {
|
||||
tmp = node;
|
||||
node = rb_next(tmp);
|
||||
clp = rb_entry(tmp, struct nfs4_client, cl_namenode);
|
||||
rb_erase(tmp, &nn->unconf_name_tree);
|
||||
destroy_client(clp);
|
||||
for (i = 0; i < CLIENT_HASH_SIZE; i++) {
|
||||
while (!list_empty(&nn->unconf_id_hashtbl[i])) {
|
||||
clp = list_entry(nn->unconf_id_hashtbl[i].next, struct nfs4_client, cl_idhash);
|
||||
destroy_client(clp);
|
||||
}
|
||||
}
|
||||
|
||||
kfree(nn->sessionid_hashtbl);
|
||||
|
|
|
|||
|
|
@ -294,7 +294,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
|
|||
READ32(nace);
|
||||
|
||||
if (nace > NFS4_ACL_MAX)
|
||||
return nfserr_resource;
|
||||
return nfserr_fbig;
|
||||
|
||||
*acl = nfs4_acl_new(nace);
|
||||
if (*acl == NULL)
|
||||
|
|
@ -1222,7 +1222,6 @@ nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
|
|||
}
|
||||
write->wr_head.iov_base = p;
|
||||
write->wr_head.iov_len = avail;
|
||||
WARN_ON(avail != (XDR_QUADLEN(avail) << 2));
|
||||
write->wr_pagelist = argp->pagelist;
|
||||
|
||||
len = XDR_QUADLEN(write->wr_buflen) << 2;
|
||||
|
|
@ -2483,6 +2482,8 @@ out_acl:
|
|||
goto out;
|
||||
}
|
||||
if (bmval2 & FATTR4_WORD2_SUPPATTR_EXCLCREAT) {
|
||||
if ((buflen -= 16) < 0)
|
||||
goto out_resource;
|
||||
WRITE32(3);
|
||||
WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD0);
|
||||
WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD1);
|
||||
|
|
@ -2499,8 +2500,10 @@ out:
|
|||
security_release_secctx(context, contextlen);
|
||||
#endif /* CONFIG_NFSD_V4_SECURITY_LABEL */
|
||||
kfree(acl);
|
||||
if (tempfh)
|
||||
if (tempfh) {
|
||||
fh_put(tempfh);
|
||||
kfree(tempfh);
|
||||
}
|
||||
return status;
|
||||
out_nfserr:
|
||||
status = nfserrno(err);
|
||||
|
|
@ -3471,6 +3474,9 @@ nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|||
struct nfsd4_test_stateid_id *stateid, *next;
|
||||
__be32 *p;
|
||||
|
||||
if (nfserr)
|
||||
return nfserr;
|
||||
|
||||
RESERVE_SPACE(4 + (4 * test_stateid->ts_num_ids));
|
||||
*p++ = htonl(test_stateid->ts_num_ids);
|
||||
|
||||
|
|
@ -3579,8 +3585,6 @@ __be32 nfsd4_check_resp_size(struct nfsd4_compoundres *resp, u32 pad)
|
|||
return 0;
|
||||
|
||||
session = resp->cstate.session;
|
||||
if (session == NULL)
|
||||
return 0;
|
||||
|
||||
if (xb->page_len == 0) {
|
||||
length = (char *)resp->p - (char *)xb->head[0].iov_base + pad;
|
||||
|
|
@ -3620,9 +3624,17 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
|
|||
BUG_ON(op->opnum < 0 || op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) ||
|
||||
!nfsd4_enc_ops[op->opnum]);
|
||||
op->status = nfsd4_enc_ops[op->opnum](resp, op->status, &op->u);
|
||||
/* nfsd4_check_drc_limit guarantees enough room for error status */
|
||||
/* nfsd4_check_resp_size guarantees enough room for error status */
|
||||
if (!op->status)
|
||||
op->status = nfsd4_check_resp_size(resp, 0);
|
||||
if (op->status == nfserr_resource && nfsd4_has_session(&resp->cstate)) {
|
||||
struct nfsd4_slot *slot = resp->cstate.slot;
|
||||
|
||||
if (slot->sl_flags & NFSD4_SLOT_CACHETHIS)
|
||||
op->status = nfserr_rep_too_big_to_cache;
|
||||
else
|
||||
op->status = nfserr_rep_too_big;
|
||||
}
|
||||
if (so) {
|
||||
so->so_replay.rp_status = op->status;
|
||||
so->so_replay.rp_buflen = (char *)resp->p - (char *)(statp+1);
|
||||
|
|
@ -3691,6 +3703,12 @@ int nfsd4_release_compoundargs(void *rq, __be32 *p, void *resp)
|
|||
int
|
||||
nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundargs *args)
|
||||
{
|
||||
if (rqstp->rq_arg.head[0].iov_len % 4) {
|
||||
/* client is nuts */
|
||||
dprintk("%s: compound not properly padded! (peeraddr=%pISc xid=0x%x)",
|
||||
__func__, svc_addr(rqstp), be32_to_cpu(rqstp->rq_xid));
|
||||
return 0;
|
||||
}
|
||||
args->p = p;
|
||||
args->end = rqstp->rq_arg.head[0].iov_base + rqstp->rq_arg.head[0].iov_len;
|
||||
args->pagelist = rqstp->rq_arg.pages;
|
||||
|
|
|
|||
|
|
@ -699,6 +699,11 @@ static ssize_t __write_ports_addfd(char *buf, struct net *net)
|
|||
if (err != 0 || fd < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (svc_alien_sock(net, fd)) {
|
||||
printk(KERN_ERR "%s: socket net is different to NFSd's one\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = nfsd_create_serv(net);
|
||||
if (err != 0)
|
||||
return err;
|
||||
|
|
|
|||
|
|
@ -282,7 +282,7 @@ void nfsd_lockd_shutdown(void);
|
|||
* reason.
|
||||
*/
|
||||
#define COMPOUND_SLACK_SPACE 140 /* OP_GETFH */
|
||||
#define COMPOUND_ERR_SLACK_SPACE 12 /* OP_SETATTR */
|
||||
#define COMPOUND_ERR_SLACK_SPACE 16 /* OP_SETATTR */
|
||||
|
||||
#define NFSD_LAUNDROMAT_MINTIMEOUT 1 /* seconds */
|
||||
|
||||
|
|
|
|||
|
|
@ -132,6 +132,17 @@ fh_init(struct svc_fh *fhp, int maxsize)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_NFSD_V3
|
||||
/*
|
||||
* The wcc data stored in current_fh should be cleared
|
||||
* between compound ops.
|
||||
*/
|
||||
static inline void
|
||||
fh_clear_wcc(struct svc_fh *fhp)
|
||||
{
|
||||
fhp->fh_post_saved = 0;
|
||||
fhp->fh_pre_saved = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill in the pre_op attr for the wcc data
|
||||
*/
|
||||
|
|
@ -152,7 +163,8 @@ fill_pre_wcc(struct svc_fh *fhp)
|
|||
|
||||
extern void fill_post_wcc(struct svc_fh *);
|
||||
#else
|
||||
#define fill_pre_wcc(ignored)
|
||||
#define fh_clear_wcc(ignored)
|
||||
#define fill_pre_wcc(ignored)
|
||||
#define fill_post_wcc(notused)
|
||||
#endif /* CONFIG_NFSD_V3 */
|
||||
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
|
|||
type = (stat->mode & S_IFMT);
|
||||
|
||||
*p++ = htonl(nfs_ftypes[type >> 12]);
|
||||
*p++ = htonl((u32) (stat->mode & S_IALLUGO));
|
||||
*p++ = htonl((u32) stat->mode);
|
||||
*p++ = htonl((u32) stat->nlink);
|
||||
*p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid));
|
||||
*p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid));
|
||||
|
|
|
|||
|
|
@ -404,6 +404,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
|
|||
umode_t ftype = 0;
|
||||
__be32 err;
|
||||
int host_err;
|
||||
bool get_write_count;
|
||||
int size_change = 0;
|
||||
|
||||
if (iap->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_SIZE))
|
||||
|
|
@ -411,10 +412,18 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
|
|||
if (iap->ia_valid & ATTR_SIZE)
|
||||
ftype = S_IFREG;
|
||||
|
||||
/* Callers that do fh_verify should do the fh_want_write: */
|
||||
get_write_count = !fhp->fh_dentry;
|
||||
|
||||
/* Get inode */
|
||||
err = fh_verify(rqstp, fhp, ftype, accmode);
|
||||
if (err)
|
||||
goto out;
|
||||
if (get_write_count) {
|
||||
host_err = fh_want_write(fhp);
|
||||
if (host_err)
|
||||
return nfserrno(host_err);
|
||||
}
|
||||
|
||||
dentry = fhp->fh_dentry;
|
||||
inode = dentry->d_inode;
|
||||
|
|
@ -1706,10 +1715,10 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
|
|||
dput(odentry);
|
||||
out_nfserr:
|
||||
err = nfserrno(host_err);
|
||||
|
||||
/* we cannot reply on fh_unlock on the two filehandles,
|
||||
/*
|
||||
* We cannot rely on fh_unlock on the two filehandles,
|
||||
* as that would do the wrong thing if the two directories
|
||||
* were the same, so again we do it by hand
|
||||
* were the same, so again we do it by hand.
|
||||
*/
|
||||
fill_post_wcc(ffhp);
|
||||
fill_post_wcc(tfhp);
|
||||
|
|
|
|||
|
|
@ -574,8 +574,6 @@ extern __be32 nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
|
|||
struct nfsd4_compound_state *,
|
||||
struct nfsd4_setclientid_confirm *setclientid_confirm);
|
||||
extern void nfsd4_store_cache_entry(struct nfsd4_compoundres *resp);
|
||||
extern __be32 nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
|
||||
struct nfsd4_sequence *seq);
|
||||
extern __be32 nfsd4_exchange_id(struct svc_rqst *rqstp,
|
||||
struct nfsd4_compound_state *, struct nfsd4_exchange_id *);
|
||||
extern __be32 nfsd4_backchannel_ctl(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_backchannel_ctl *);
|
||||
|
|
|
|||
Loading…
Reference in a new issue