mirror of
https://github.com/torvalds/linux.git
synced 2024-11-28 15:11:31 +00:00
Merge branch 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6
* 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6: nfs: don't lose MS_SYNCHRONOUS on remount of noac mount NFS: Return meaningful status from decode_secinfo() NFSv4: Ensure we request the ordinary fileid when doing readdirplus NFSv4: Ensure that clientid and session establishment can time out SUNRPC: Allow RPC calls to return ETIMEDOUT instead of EIO NFSv4.1: Don't loop forever in nfs4_proc_create_session NFSv4: Handle NFS4ERR_WRONGSEC outside of nfs4_handle_exception() NFSv4.1: Don't update sequence number if rpc_task is not sent NFSv4.1: Ensure state manager thread dies on last umount SUNRPC: Fix the SUNRPC Kerberos V RPCSEC_GSS module dependencies NFS: Use correct variable for page bounds checking NFS: don't negotiate when user specifies sec flavor NFS: Attempt mount with default sec flavor first NFS: flav_array honors NFS_MAX_SECFLAVORS NFS: Fix infinite loop in gss_create_upcall() Don't mark_inode_dirty_sync() while holding lock NFS: Get rid of pointless test in nfs_commit_done NFS: Remove unused argument from nfs_find_best_sec() NFS: Eliminate duplicate call to nfs_mark_request_dirty NFS: Remove dead code from nfs_fs_mount()
This commit is contained in:
commit
9cab1ba421
@ -119,7 +119,7 @@ Elong:
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NFS_V4
|
||||
static rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *flavors, struct inode *inode)
|
||||
static rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *flavors)
|
||||
{
|
||||
struct gss_api_mech *mech;
|
||||
struct xdr_netobj oid;
|
||||
@ -166,7 +166,7 @@ static int nfs_negotiate_security(const struct dentry *parent,
|
||||
}
|
||||
flavors = page_address(page);
|
||||
ret = secinfo(parent->d_inode, &dentry->d_name, flavors);
|
||||
*flavor = nfs_find_best_sec(flavors, dentry->d_inode);
|
||||
*flavor = nfs_find_best_sec(flavors);
|
||||
put_page(page);
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,7 @@ enum nfs4_client_state {
|
||||
NFS4CLNT_LAYOUTRECALL,
|
||||
NFS4CLNT_SESSION_RESET,
|
||||
NFS4CLNT_RECALL_SLOT,
|
||||
NFS4CLNT_LEASE_CONFIRM,
|
||||
};
|
||||
|
||||
enum nfs4_session_state {
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include <linux/nfs4.h>
|
||||
#include <linux/nfs_fs.h>
|
||||
#include <linux/nfs_page.h>
|
||||
#include <linux/nfs_mount.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/module.h>
|
||||
@ -443,8 +444,8 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *
|
||||
if (res->sr_status == 1)
|
||||
res->sr_status = NFS_OK;
|
||||
|
||||
/* -ERESTARTSYS can result in skipping nfs41_sequence_setup */
|
||||
if (!res->sr_slot)
|
||||
/* don't increment the sequence number if the task wasn't sent */
|
||||
if (!RPC_WAS_SENT(task))
|
||||
goto out;
|
||||
|
||||
/* Check the SEQUENCE operation status */
|
||||
@ -2185,9 +2186,14 @@ static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
|
||||
struct nfs4_exception exception = { };
|
||||
int err;
|
||||
do {
|
||||
err = nfs4_handle_exception(server,
|
||||
_nfs4_lookup_root(server, fhandle, info),
|
||||
&exception);
|
||||
err = _nfs4_lookup_root(server, fhandle, info);
|
||||
switch (err) {
|
||||
case 0:
|
||||
case -NFS4ERR_WRONGSEC:
|
||||
break;
|
||||
default:
|
||||
err = nfs4_handle_exception(server, err, &exception);
|
||||
}
|
||||
} while (exception.retry);
|
||||
return err;
|
||||
}
|
||||
@ -2208,25 +2214,47 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nfs4_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
|
||||
struct nfs_fsinfo *info)
|
||||
{
|
||||
int i, len, status = 0;
|
||||
rpc_authflavor_t flav_array[NFS_MAX_SECFLAVORS];
|
||||
|
||||
len = gss_mech_list_pseudoflavors(&flav_array[0]);
|
||||
flav_array[len] = RPC_AUTH_NULL;
|
||||
len += 1;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
status = nfs4_lookup_root_sec(server, fhandle, info, flav_array[i]);
|
||||
if (status == -NFS4ERR_WRONGSEC || status == -EACCES)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* -EACCESS could mean that the user doesn't have correct permissions
|
||||
* to access the mount. It could also mean that we tried to mount
|
||||
* with a gss auth flavor, but rpc.gssd isn't running. Either way,
|
||||
* existing mount programs don't handle -EACCES very well so it should
|
||||
* be mapped to -EPERM instead.
|
||||
*/
|
||||
if (status == -EACCES)
|
||||
status = -EPERM;
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* get the file handle for the "/" directory on the server
|
||||
*/
|
||||
static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
|
||||
struct nfs_fsinfo *info)
|
||||
{
|
||||
int i, len, status = 0;
|
||||
rpc_authflavor_t flav_array[NFS_MAX_SECFLAVORS + 2];
|
||||
|
||||
flav_array[0] = RPC_AUTH_UNIX;
|
||||
len = gss_mech_list_pseudoflavors(&flav_array[1]);
|
||||
flav_array[1+len] = RPC_AUTH_NULL;
|
||||
len += 2;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
status = nfs4_lookup_root_sec(server, fhandle, info, flav_array[i]);
|
||||
if (status != -EPERM)
|
||||
break;
|
||||
}
|
||||
int status = nfs4_lookup_root(server, fhandle, info);
|
||||
if ((status == -NFS4ERR_WRONGSEC) && !(server->flags & NFS_MOUNT_SECFLAVOUR))
|
||||
/*
|
||||
* A status of -NFS4ERR_WRONGSEC will be mapped to -EPERM
|
||||
* by nfs4_map_errors() as this function exits.
|
||||
*/
|
||||
status = nfs4_find_root_sec(server, fhandle, info);
|
||||
if (status == 0)
|
||||
status = nfs4_server_capabilities(server, fhandle);
|
||||
if (status == 0)
|
||||
@ -3723,21 +3751,20 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
|
||||
sizeof(setclientid.sc_uaddr), "%s.%u.%u",
|
||||
clp->cl_ipaddr, port >> 8, port & 255);
|
||||
|
||||
status = rpc_call_sync(clp->cl_rpcclient, &msg, 0);
|
||||
status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
|
||||
if (status != -NFS4ERR_CLID_INUSE)
|
||||
break;
|
||||
if (signalled())
|
||||
if (loop != 0) {
|
||||
++clp->cl_id_uniquifier;
|
||||
break;
|
||||
if (loop++ & 1)
|
||||
ssleep(clp->cl_lease_time / HZ + 1);
|
||||
else
|
||||
if (++clp->cl_id_uniquifier == 0)
|
||||
break;
|
||||
}
|
||||
++loop;
|
||||
ssleep(clp->cl_lease_time / HZ + 1);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp,
|
||||
int nfs4_proc_setclientid_confirm(struct nfs_client *clp,
|
||||
struct nfs4_setclientid_res *arg,
|
||||
struct rpc_cred *cred)
|
||||
{
|
||||
@ -3752,7 +3779,7 @@ static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp,
|
||||
int status;
|
||||
|
||||
now = jiffies;
|
||||
status = rpc_call_sync(clp->cl_rpcclient, &msg, 0);
|
||||
status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
|
||||
if (status == 0) {
|
||||
spin_lock(&clp->cl_lock);
|
||||
clp->cl_lease_time = fsinfo.lease_time * HZ;
|
||||
@ -3762,26 +3789,6 @@ static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp,
|
||||
return status;
|
||||
}
|
||||
|
||||
int nfs4_proc_setclientid_confirm(struct nfs_client *clp,
|
||||
struct nfs4_setclientid_res *arg,
|
||||
struct rpc_cred *cred)
|
||||
{
|
||||
long timeout = 0;
|
||||
int err;
|
||||
do {
|
||||
err = _nfs4_proc_setclientid_confirm(clp, arg, cred);
|
||||
switch (err) {
|
||||
case 0:
|
||||
return err;
|
||||
case -NFS4ERR_RESOURCE:
|
||||
/* The IBM lawyers misread another document! */
|
||||
case -NFS4ERR_DELAY:
|
||||
err = nfs4_delay(clp->cl_rpcclient, &timeout);
|
||||
}
|
||||
} while (err == 0);
|
||||
return err;
|
||||
}
|
||||
|
||||
struct nfs4_delegreturndata {
|
||||
struct nfs4_delegreturnargs args;
|
||||
struct nfs4_delegreturnres res;
|
||||
@ -4786,7 +4793,7 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
|
||||
init_utsname()->domainname,
|
||||
clp->cl_rpcclient->cl_auth->au_flavor);
|
||||
|
||||
status = rpc_call_sync(clp->cl_rpcclient, &msg, 0);
|
||||
status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
|
||||
if (!status)
|
||||
status = nfs4_check_cl_exchange_flags(clp->cl_exchange_flags);
|
||||
dprintk("<-- %s status= %d\n", __func__, status);
|
||||
@ -4869,7 +4876,8 @@ int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo)
|
||||
.rpc_client = clp->cl_rpcclient,
|
||||
.rpc_message = &msg,
|
||||
.callback_ops = &nfs4_get_lease_time_ops,
|
||||
.callback_data = &data
|
||||
.callback_data = &data,
|
||||
.flags = RPC_TASK_TIMEOUT,
|
||||
};
|
||||
int status;
|
||||
|
||||
@ -5171,7 +5179,7 @@ static int _nfs4_proc_create_session(struct nfs_client *clp)
|
||||
nfs4_init_channel_attrs(&args);
|
||||
args.flags = (SESSION4_PERSIST | SESSION4_BACK_CHAN);
|
||||
|
||||
status = rpc_call_sync(session->clp->cl_rpcclient, &msg, 0);
|
||||
status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
|
||||
|
||||
if (!status)
|
||||
/* Verify the session's negotiated channel_attrs values */
|
||||
@ -5194,20 +5202,10 @@ int nfs4_proc_create_session(struct nfs_client *clp)
|
||||
int status;
|
||||
unsigned *ptr;
|
||||
struct nfs4_session *session = clp->cl_session;
|
||||
long timeout = 0;
|
||||
int err;
|
||||
|
||||
dprintk("--> %s clp=%p session=%p\n", __func__, clp, session);
|
||||
|
||||
do {
|
||||
status = _nfs4_proc_create_session(clp);
|
||||
if (status == -NFS4ERR_DELAY) {
|
||||
err = nfs4_delay(clp->cl_rpcclient, &timeout);
|
||||
if (err)
|
||||
status = err;
|
||||
}
|
||||
} while (status == -NFS4ERR_DELAY);
|
||||
|
||||
status = _nfs4_proc_create_session(clp);
|
||||
if (status)
|
||||
goto out;
|
||||
|
||||
@ -5248,7 +5246,7 @@ int nfs4_proc_destroy_session(struct nfs4_session *session)
|
||||
msg.rpc_argp = session;
|
||||
msg.rpc_resp = NULL;
|
||||
msg.rpc_cred = NULL;
|
||||
status = rpc_call_sync(session->clp->cl_rpcclient, &msg, 0);
|
||||
status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
|
||||
|
||||
if (status)
|
||||
printk(KERN_WARNING
|
||||
|
@ -64,10 +64,15 @@ static LIST_HEAD(nfs4_clientid_list);
|
||||
|
||||
int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
|
||||
{
|
||||
struct nfs4_setclientid_res clid;
|
||||
struct nfs4_setclientid_res clid = {
|
||||
.clientid = clp->cl_clientid,
|
||||
.confirm = clp->cl_confirm,
|
||||
};
|
||||
unsigned short port;
|
||||
int status;
|
||||
|
||||
if (test_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state))
|
||||
goto do_confirm;
|
||||
port = nfs_callback_tcpport;
|
||||
if (clp->cl_addr.ss_family == AF_INET6)
|
||||
port = nfs_callback_tcpport6;
|
||||
@ -75,10 +80,14 @@ int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
|
||||
status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, port, cred, &clid);
|
||||
if (status != 0)
|
||||
goto out;
|
||||
clp->cl_clientid = clid.clientid;
|
||||
clp->cl_confirm = clid.confirm;
|
||||
set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
|
||||
do_confirm:
|
||||
status = nfs4_proc_setclientid_confirm(clp, &clid, cred);
|
||||
if (status != 0)
|
||||
goto out;
|
||||
clp->cl_clientid = clid.clientid;
|
||||
clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
|
||||
nfs4_schedule_state_renewal(clp);
|
||||
out:
|
||||
return status;
|
||||
@ -230,13 +239,18 @@ int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (test_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state))
|
||||
goto do_confirm;
|
||||
nfs4_begin_drain_session(clp);
|
||||
status = nfs4_proc_exchange_id(clp, cred);
|
||||
if (status != 0)
|
||||
goto out;
|
||||
set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
|
||||
do_confirm:
|
||||
status = nfs4_proc_create_session(clp);
|
||||
if (status != 0)
|
||||
goto out;
|
||||
clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
|
||||
nfs41_setup_state_renewal(clp);
|
||||
nfs_mark_client_ready(clp, NFS_CS_READY);
|
||||
out:
|
||||
@ -1584,20 +1598,23 @@ static int nfs4_recall_slot(struct nfs_client *clp) { return 0; }
|
||||
*/
|
||||
static void nfs4_set_lease_expired(struct nfs_client *clp, int status)
|
||||
{
|
||||
if (nfs4_has_session(clp)) {
|
||||
switch (status) {
|
||||
case -NFS4ERR_DELAY:
|
||||
case -NFS4ERR_CLID_INUSE:
|
||||
case -EAGAIN:
|
||||
break;
|
||||
switch (status) {
|
||||
case -NFS4ERR_CLID_INUSE:
|
||||
case -NFS4ERR_STALE_CLIENTID:
|
||||
clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
|
||||
break;
|
||||
case -NFS4ERR_DELAY:
|
||||
case -ETIMEDOUT:
|
||||
case -EAGAIN:
|
||||
ssleep(1);
|
||||
break;
|
||||
|
||||
case -EKEYEXPIRED:
|
||||
nfs4_warn_keyexpired(clp->cl_hostname);
|
||||
case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery
|
||||
* in nfs4_exchange_id */
|
||||
default:
|
||||
return;
|
||||
}
|
||||
case -EKEYEXPIRED:
|
||||
nfs4_warn_keyexpired(clp->cl_hostname);
|
||||
case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery
|
||||
* in nfs4_exchange_id */
|
||||
default:
|
||||
return;
|
||||
}
|
||||
set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
|
||||
}
|
||||
@ -1607,7 +1624,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
|
||||
int status = 0;
|
||||
|
||||
/* Ensure exclusive access to NFSv4 state */
|
||||
for(;;) {
|
||||
do {
|
||||
if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) {
|
||||
/* We're going to have to re-establish a clientid */
|
||||
status = nfs4_reclaim_lease(clp);
|
||||
@ -1691,7 +1708,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
|
||||
break;
|
||||
if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0)
|
||||
break;
|
||||
}
|
||||
} while (atomic_read(&clp->cl_count) > 1);
|
||||
return;
|
||||
out_error:
|
||||
printk(KERN_WARNING "Error: state manager failed on NFSv4 server %s"
|
||||
|
@ -1452,26 +1452,25 @@ static void encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args,
|
||||
|
||||
static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req, struct compound_hdr *hdr)
|
||||
{
|
||||
uint32_t attrs[2] = {0, 0};
|
||||
uint32_t attrs[2] = {
|
||||
FATTR4_WORD0_RDATTR_ERROR,
|
||||
FATTR4_WORD1_MOUNTED_ON_FILEID,
|
||||
};
|
||||
uint32_t dircount = readdir->count >> 1;
|
||||
__be32 *p;
|
||||
|
||||
if (readdir->plus) {
|
||||
attrs[0] |= FATTR4_WORD0_TYPE|FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE|
|
||||
FATTR4_WORD0_FSID|FATTR4_WORD0_FILEHANDLE;
|
||||
FATTR4_WORD0_FSID|FATTR4_WORD0_FILEHANDLE|FATTR4_WORD0_FILEID;
|
||||
attrs[1] |= FATTR4_WORD1_MODE|FATTR4_WORD1_NUMLINKS|FATTR4_WORD1_OWNER|
|
||||
FATTR4_WORD1_OWNER_GROUP|FATTR4_WORD1_RAWDEV|
|
||||
FATTR4_WORD1_SPACE_USED|FATTR4_WORD1_TIME_ACCESS|
|
||||
FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY;
|
||||
dircount >>= 1;
|
||||
}
|
||||
attrs[0] |= FATTR4_WORD0_RDATTR_ERROR|FATTR4_WORD0_FILEID;
|
||||
attrs[1] |= FATTR4_WORD1_MOUNTED_ON_FILEID;
|
||||
/* Switch to mounted_on_fileid if the server supports it */
|
||||
if (readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)
|
||||
attrs[0] &= ~FATTR4_WORD0_FILEID;
|
||||
else
|
||||
attrs[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID;
|
||||
/* Use mounted_on_fileid only if the server supports it */
|
||||
if (!(readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID))
|
||||
attrs[0] |= FATTR4_WORD0_FILEID;
|
||||
|
||||
p = reserve_space(xdr, 12+NFS4_VERIFIER_SIZE+20);
|
||||
*p++ = cpu_to_be32(OP_READDIR);
|
||||
@ -3140,7 +3139,7 @@ static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitma
|
||||
goto out_overflow;
|
||||
xdr_decode_hyper(p, fileid);
|
||||
bitmap[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID;
|
||||
ret = NFS_ATTR_FATTR_FILEID;
|
||||
ret = NFS_ATTR_FATTR_MOUNTED_ON_FILEID;
|
||||
}
|
||||
dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid);
|
||||
return ret;
|
||||
@ -4002,7 +4001,6 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
|
||||
{
|
||||
int status;
|
||||
umode_t fmode = 0;
|
||||
uint64_t fileid;
|
||||
uint32_t type;
|
||||
|
||||
status = decode_attr_type(xdr, bitmap, &type);
|
||||
@ -4101,13 +4099,10 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
|
||||
goto xdr_error;
|
||||
fattr->valid |= status;
|
||||
|
||||
status = decode_attr_mounted_on_fileid(xdr, bitmap, &fileid);
|
||||
status = decode_attr_mounted_on_fileid(xdr, bitmap, &fattr->mounted_on_fileid);
|
||||
if (status < 0)
|
||||
goto xdr_error;
|
||||
if (status != 0 && !(fattr->valid & status)) {
|
||||
fattr->fileid = fileid;
|
||||
fattr->valid |= status;
|
||||
}
|
||||
fattr->valid |= status;
|
||||
|
||||
xdr_error:
|
||||
dprintk("%s: xdr returned %d\n", __func__, -status);
|
||||
@ -4838,17 +4833,21 @@ static int decode_secinfo(struct xdr_stream *xdr, struct nfs4_secinfo_res *res)
|
||||
struct nfs4_secinfo_flavor *sec_flavor;
|
||||
int status;
|
||||
__be32 *p;
|
||||
int i;
|
||||
int i, num_flavors;
|
||||
|
||||
status = decode_op_hdr(xdr, OP_SECINFO);
|
||||
if (status)
|
||||
goto out;
|
||||
p = xdr_inline_decode(xdr, 4);
|
||||
if (unlikely(!p))
|
||||
goto out_overflow;
|
||||
res->flavors->num_flavors = be32_to_cpup(p);
|
||||
|
||||
for (i = 0; i < res->flavors->num_flavors; i++) {
|
||||
res->flavors->num_flavors = 0;
|
||||
num_flavors = be32_to_cpup(p);
|
||||
|
||||
for (i = 0; i < num_flavors; i++) {
|
||||
sec_flavor = &res->flavors->flavors[i];
|
||||
if ((char *)&sec_flavor[1] - (char *)res > PAGE_SIZE)
|
||||
if ((char *)&sec_flavor[1] - (char *)res->flavors > PAGE_SIZE)
|
||||
break;
|
||||
|
||||
p = xdr_inline_decode(xdr, 4);
|
||||
@ -4857,13 +4856,15 @@ static int decode_secinfo(struct xdr_stream *xdr, struct nfs4_secinfo_res *res)
|
||||
sec_flavor->flavor = be32_to_cpup(p);
|
||||
|
||||
if (sec_flavor->flavor == RPC_AUTH_GSS) {
|
||||
if (decode_secinfo_gss(xdr, sec_flavor))
|
||||
break;
|
||||
status = decode_secinfo_gss(xdr, sec_flavor);
|
||||
if (status)
|
||||
goto out;
|
||||
}
|
||||
res->flavors->num_flavors++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out:
|
||||
return status;
|
||||
out_overflow:
|
||||
print_overflow_msg(__func__, xdr);
|
||||
return -EIO;
|
||||
@ -6408,7 +6409,9 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
|
||||
if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh,
|
||||
entry->server, 1) < 0)
|
||||
goto out_overflow;
|
||||
if (entry->fattr->valid & NFS_ATTR_FATTR_FILEID)
|
||||
if (entry->fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID)
|
||||
entry->ino = entry->fattr->mounted_on_fileid;
|
||||
else if (entry->fattr->valid & NFS_ATTR_FATTR_FILEID)
|
||||
entry->ino = entry->fattr->fileid;
|
||||
|
||||
entry->d_type = DT_UNKNOWN;
|
||||
|
@ -1004,6 +1004,7 @@ pnfs_set_layoutcommit(struct nfs_write_data *wdata)
|
||||
{
|
||||
struct nfs_inode *nfsi = NFS_I(wdata->inode);
|
||||
loff_t end_pos = wdata->args.offset + wdata->res.count;
|
||||
bool mark_as_dirty = false;
|
||||
|
||||
spin_lock(&nfsi->vfs_inode.i_lock);
|
||||
if (!test_and_set_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) {
|
||||
@ -1011,13 +1012,18 @@ pnfs_set_layoutcommit(struct nfs_write_data *wdata)
|
||||
get_lseg(wdata->lseg);
|
||||
wdata->lseg->pls_lc_cred =
|
||||
get_rpccred(wdata->args.context->state->owner->so_cred);
|
||||
mark_inode_dirty_sync(wdata->inode);
|
||||
mark_as_dirty = true;
|
||||
dprintk("%s: Set layoutcommit for inode %lu ",
|
||||
__func__, wdata->inode->i_ino);
|
||||
}
|
||||
if (end_pos > wdata->lseg->pls_end_pos)
|
||||
wdata->lseg->pls_end_pos = end_pos;
|
||||
spin_unlock(&nfsi->vfs_inode.i_lock);
|
||||
|
||||
/* if pnfs_layoutcommit_inode() runs between inode locks, the next one
|
||||
* will be a noop because NFS_INO_LAYOUTCOMMIT will not be set */
|
||||
if (mark_as_dirty)
|
||||
mark_inode_dirty_sync(wdata->inode);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pnfs_set_layoutcommit);
|
||||
|
||||
|
@ -1004,6 +1004,7 @@ static int nfs_parse_security_flavors(char *value,
|
||||
return 0;
|
||||
}
|
||||
|
||||
mnt->flags |= NFS_MOUNT_SECFLAVOUR;
|
||||
mnt->auth_flavor_len = 1;
|
||||
return 1;
|
||||
}
|
||||
@ -1976,6 +1977,15 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data)
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* noac is a special case. It implies -o sync, but that's not
|
||||
* necessarily reflected in the mtab options. do_remount_sb
|
||||
* will clear MS_SYNCHRONOUS if -o sync wasn't specified in the
|
||||
* remount options, so we have to explicitly reset it.
|
||||
*/
|
||||
if (data->flags & NFS_MOUNT_NOAC)
|
||||
*flags |= MS_SYNCHRONOUS;
|
||||
|
||||
/* compare new mount options with old ones */
|
||||
error = nfs_compare_remount_data(nfss, data);
|
||||
out:
|
||||
@ -2235,8 +2245,7 @@ static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
|
||||
if (!s->s_root) {
|
||||
/* initial superblock/root creation */
|
||||
nfs_fill_super(s, data);
|
||||
nfs_fscache_get_super_cookie(
|
||||
s, data ? data->fscache_uniq : NULL, NULL);
|
||||
nfs_fscache_get_super_cookie(s, data->fscache_uniq, NULL);
|
||||
}
|
||||
|
||||
mntroot = nfs_get_root(s, mntfh, dev_name);
|
||||
|
@ -680,7 +680,6 @@ static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page,
|
||||
req = nfs_setup_write_request(ctx, page, offset, count);
|
||||
if (IS_ERR(req))
|
||||
return PTR_ERR(req);
|
||||
nfs_mark_request_dirty(req);
|
||||
/* Update file length */
|
||||
nfs_grow_file(page, offset, count);
|
||||
nfs_mark_uptodate(page, req->wb_pgbase, req->wb_bytes);
|
||||
@ -1418,8 +1417,7 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata)
|
||||
task->tk_pid, task->tk_status);
|
||||
|
||||
/* Call the NFS version-specific code */
|
||||
if (NFS_PROTO(data->inode)->commit_done(task, data) != 0)
|
||||
return;
|
||||
NFS_PROTO(data->inode)->commit_done(task, data);
|
||||
}
|
||||
|
||||
void nfs_commit_release_pages(struct nfs_write_data *data)
|
||||
|
@ -47,6 +47,7 @@ struct nfs_client {
|
||||
|
||||
#ifdef CONFIG_NFS_V4
|
||||
u64 cl_clientid; /* constant */
|
||||
nfs4_verifier cl_confirm; /* Clientid verifier */
|
||||
unsigned long cl_state;
|
||||
|
||||
spinlock_t cl_lock;
|
||||
|
@ -50,6 +50,7 @@ struct nfs_fattr {
|
||||
} du;
|
||||
struct nfs_fsid fsid;
|
||||
__u64 fileid;
|
||||
__u64 mounted_on_fileid;
|
||||
struct timespec atime;
|
||||
struct timespec mtime;
|
||||
struct timespec ctime;
|
||||
@ -83,6 +84,7 @@ struct nfs_fattr {
|
||||
#define NFS_ATTR_FATTR_PRECHANGE (1U << 18)
|
||||
#define NFS_ATTR_FATTR_V4_REFERRAL (1U << 19) /* NFSv4 referral */
|
||||
#define NFS_ATTR_FATTR_MOUNTPOINT (1U << 20) /* Treat as mountpoint */
|
||||
#define NFS_ATTR_FATTR_MOUNTED_ON_FILEID (1U << 21)
|
||||
|
||||
#define NFS_ATTR_FATTR (NFS_ATTR_FATTR_TYPE \
|
||||
| NFS_ATTR_FATTR_MODE \
|
||||
|
@ -127,13 +127,16 @@ struct rpc_task_setup {
|
||||
#define RPC_TASK_KILLED 0x0100 /* task was killed */
|
||||
#define RPC_TASK_SOFT 0x0200 /* Use soft timeouts */
|
||||
#define RPC_TASK_SOFTCONN 0x0400 /* Fail if can't connect */
|
||||
#define RPC_TASK_SENT 0x0800 /* message was sent */
|
||||
#define RPC_TASK_TIMEOUT 0x1000 /* fail with ETIMEDOUT on timeout */
|
||||
|
||||
#define RPC_IS_ASYNC(t) ((t)->tk_flags & RPC_TASK_ASYNC)
|
||||
#define RPC_IS_SWAPPER(t) ((t)->tk_flags & RPC_TASK_SWAPPER)
|
||||
#define RPC_DO_ROOTOVERRIDE(t) ((t)->tk_flags & RPC_TASK_ROOTCREDS)
|
||||
#define RPC_ASSASSINATED(t) ((t)->tk_flags & RPC_TASK_KILLED)
|
||||
#define RPC_IS_SOFT(t) ((t)->tk_flags & RPC_TASK_SOFT)
|
||||
#define RPC_IS_SOFT(t) ((t)->tk_flags & (RPC_TASK_SOFT|RPC_TASK_TIMEOUT))
|
||||
#define RPC_IS_SOFTCONN(t) ((t)->tk_flags & RPC_TASK_SOFTCONN)
|
||||
#define RPC_WAS_SENT(t) ((t)->tk_flags & RPC_TASK_SENT)
|
||||
|
||||
#define RPC_TASK_RUNNING 0
|
||||
#define RPC_TASK_QUEUED 1
|
||||
|
@ -18,14 +18,13 @@ config SUNRPC_XPRT_RDMA
|
||||
If unsure, say N.
|
||||
|
||||
config RPCSEC_GSS_KRB5
|
||||
tristate
|
||||
tristate "Secure RPC: Kerberos V mechanism"
|
||||
depends on SUNRPC && CRYPTO
|
||||
prompt "Secure RPC: Kerberos V mechanism" if !(NFS_V4 || NFSD_V4)
|
||||
depends on CRYPTO_MD5 && CRYPTO_DES && CRYPTO_CBC && CRYPTO_CTS
|
||||
depends on CRYPTO_ECB && CRYPTO_HMAC && CRYPTO_SHA1 && CRYPTO_AES
|
||||
depends on CRYPTO_ARC4
|
||||
default y
|
||||
select SUNRPC_GSS
|
||||
select CRYPTO_MD5
|
||||
select CRYPTO_DES
|
||||
select CRYPTO_CBC
|
||||
help
|
||||
Choose Y here to enable Secure RPC using the Kerberos version 5
|
||||
GSS-API mechanism (RFC 1964).
|
||||
|
@ -520,7 +520,7 @@ gss_refresh_upcall(struct rpc_task *task)
|
||||
warn_gssd();
|
||||
task->tk_timeout = 15*HZ;
|
||||
rpc_sleep_on(&pipe_version_rpc_waitqueue, task, NULL);
|
||||
return 0;
|
||||
return -EAGAIN;
|
||||
}
|
||||
if (IS_ERR(gss_msg)) {
|
||||
err = PTR_ERR(gss_msg);
|
||||
@ -563,10 +563,12 @@ retry:
|
||||
if (PTR_ERR(gss_msg) == -EAGAIN) {
|
||||
err = wait_event_interruptible_timeout(pipe_version_waitqueue,
|
||||
pipe_version >= 0, 15*HZ);
|
||||
if (pipe_version < 0) {
|
||||
warn_gssd();
|
||||
err = -EACCES;
|
||||
}
|
||||
if (err)
|
||||
goto out;
|
||||
if (pipe_version < 0)
|
||||
warn_gssd();
|
||||
goto retry;
|
||||
}
|
||||
if (IS_ERR(gss_msg)) {
|
||||
|
@ -1508,7 +1508,10 @@ call_timeout(struct rpc_task *task)
|
||||
if (clnt->cl_chatty)
|
||||
printk(KERN_NOTICE "%s: server %s not responding, timed out\n",
|
||||
clnt->cl_protname, clnt->cl_server);
|
||||
rpc_exit(task, -EIO);
|
||||
if (task->tk_flags & RPC_TASK_TIMEOUT)
|
||||
rpc_exit(task, -ETIMEDOUT);
|
||||
else
|
||||
rpc_exit(task, -EIO);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -906,6 +906,7 @@ void xprt_transmit(struct rpc_task *task)
|
||||
}
|
||||
|
||||
dprintk("RPC: %5u xmit complete\n", task->tk_pid);
|
||||
task->tk_flags |= RPC_TASK_SENT;
|
||||
spin_lock_bh(&xprt->transport_lock);
|
||||
|
||||
xprt->ops->set_retrans_timeout(task);
|
||||
|
Loading…
Reference in New Issue
Block a user