Merge branch 'nfs-for-3.2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
* 'nfs-for-3.2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (26 commits) Check validity of cl_rpcclient in nfs_server_list_show NFS: Get rid of the nfs_rdata_mempool NFS: Don't rely on PageError in nfs_readpage_release_partial NFS: Get rid of unnecessary calls to ClearPageError() in read code NFS: Get rid of nfs_restart_rpc() NFS: Get rid of the unused nfs_write_data->flags field NFS: Get rid of the unused nfs_read_data->flags field NFSv4: Translate NFS4ERR_BADNAME into ENOENT when applied to a lookup NFS: Remove the unused "lookupfh()" version of nfs4_proc_lookup() NFS: Use the inode->i_version to cache NFSv4 change attribute information SUNRPC: Remove unnecessary export of rpc_sockaddr2uaddr SUNRPC: Fix rpc_sockaddr2uaddr nfs/super.c: local functions should be static pnfsblock: fix writeback deadlock pnfsblock: fix NULL pointer dereference pnfs: recoalesce when ld read pagelist fails pnfs: recoalesce when ld write pagelist fails pnfs: make _set_lo_fail generic pnfsblock: add missing rpc_put_mount and path_put SUNRPC/NFS: make rpc pipe upcall generic ...
This commit is contained in:
commit
ef78cc75f1
@ -176,17 +176,6 @@ retry:
|
|||||||
return bio;
|
return bio;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bl_set_lo_fail(struct pnfs_layout_segment *lseg)
|
|
||||||
{
|
|
||||||
if (lseg->pls_range.iomode == IOMODE_RW) {
|
|
||||||
dprintk("%s Setting layout IOMODE_RW fail bit\n", __func__);
|
|
||||||
set_bit(lo_fail_bit(IOMODE_RW), &lseg->pls_layout->plh_flags);
|
|
||||||
} else {
|
|
||||||
dprintk("%s Setting layout IOMODE_READ fail bit\n", __func__);
|
|
||||||
set_bit(lo_fail_bit(IOMODE_READ), &lseg->pls_layout->plh_flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This is basically copied from mpage_end_io_read */
|
/* This is basically copied from mpage_end_io_read */
|
||||||
static void bl_end_io_read(struct bio *bio, int err)
|
static void bl_end_io_read(struct bio *bio, int err)
|
||||||
{
|
{
|
||||||
@ -206,7 +195,7 @@ static void bl_end_io_read(struct bio *bio, int err)
|
|||||||
if (!uptodate) {
|
if (!uptodate) {
|
||||||
if (!rdata->pnfs_error)
|
if (!rdata->pnfs_error)
|
||||||
rdata->pnfs_error = -EIO;
|
rdata->pnfs_error = -EIO;
|
||||||
bl_set_lo_fail(rdata->lseg);
|
pnfs_set_lo_fail(rdata->lseg);
|
||||||
}
|
}
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
put_parallel(par);
|
put_parallel(par);
|
||||||
@ -303,6 +292,7 @@ bl_read_pagelist(struct nfs_read_data *rdata)
|
|||||||
bl_end_io_read, par);
|
bl_end_io_read, par);
|
||||||
if (IS_ERR(bio)) {
|
if (IS_ERR(bio)) {
|
||||||
rdata->pnfs_error = PTR_ERR(bio);
|
rdata->pnfs_error = PTR_ERR(bio);
|
||||||
|
bio = NULL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -370,7 +360,7 @@ static void bl_end_io_write_zero(struct bio *bio, int err)
|
|||||||
if (!uptodate) {
|
if (!uptodate) {
|
||||||
if (!wdata->pnfs_error)
|
if (!wdata->pnfs_error)
|
||||||
wdata->pnfs_error = -EIO;
|
wdata->pnfs_error = -EIO;
|
||||||
bl_set_lo_fail(wdata->lseg);
|
pnfs_set_lo_fail(wdata->lseg);
|
||||||
}
|
}
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
put_parallel(par);
|
put_parallel(par);
|
||||||
@ -386,7 +376,7 @@ static void bl_end_io_write(struct bio *bio, int err)
|
|||||||
if (!uptodate) {
|
if (!uptodate) {
|
||||||
if (!wdata->pnfs_error)
|
if (!wdata->pnfs_error)
|
||||||
wdata->pnfs_error = -EIO;
|
wdata->pnfs_error = -EIO;
|
||||||
bl_set_lo_fail(wdata->lseg);
|
pnfs_set_lo_fail(wdata->lseg);
|
||||||
}
|
}
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
put_parallel(par);
|
put_parallel(par);
|
||||||
@ -543,6 +533,11 @@ bl_write_pagelist(struct nfs_write_data *wdata, int sync)
|
|||||||
fill_invalid_ext:
|
fill_invalid_ext:
|
||||||
dprintk("%s need to zero %d pages\n", __func__, npg_zero);
|
dprintk("%s need to zero %d pages\n", __func__, npg_zero);
|
||||||
for (;npg_zero > 0; npg_zero--) {
|
for (;npg_zero > 0; npg_zero--) {
|
||||||
|
if (bl_is_sector_init(be->be_inval, isect)) {
|
||||||
|
dprintk("isect %llu already init\n",
|
||||||
|
(unsigned long long)isect);
|
||||||
|
goto next_page;
|
||||||
|
}
|
||||||
/* page ref released in bl_end_io_write_zero */
|
/* page ref released in bl_end_io_write_zero */
|
||||||
index = isect >> PAGE_CACHE_SECTOR_SHIFT;
|
index = isect >> PAGE_CACHE_SECTOR_SHIFT;
|
||||||
dprintk("%s zero %dth page: index %lu isect %llu\n",
|
dprintk("%s zero %dth page: index %lu isect %llu\n",
|
||||||
@ -562,8 +557,7 @@ fill_invalid_ext:
|
|||||||
* PageUptodate: It was read before
|
* PageUptodate: It was read before
|
||||||
* sector_initialized: already written out
|
* sector_initialized: already written out
|
||||||
*/
|
*/
|
||||||
if (PageDirty(page) || PageWriteback(page) ||
|
if (PageDirty(page) || PageWriteback(page)) {
|
||||||
bl_is_sector_init(be->be_inval, isect)) {
|
|
||||||
print_page(page);
|
print_page(page);
|
||||||
unlock_page(page);
|
unlock_page(page);
|
||||||
page_cache_release(page);
|
page_cache_release(page);
|
||||||
@ -592,6 +586,7 @@ fill_invalid_ext:
|
|||||||
bl_end_io_write_zero, par);
|
bl_end_io_write_zero, par);
|
||||||
if (IS_ERR(bio)) {
|
if (IS_ERR(bio)) {
|
||||||
wdata->pnfs_error = PTR_ERR(bio);
|
wdata->pnfs_error = PTR_ERR(bio);
|
||||||
|
bio = NULL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
/* FIXME: This should be done in bi_end_io */
|
/* FIXME: This should be done in bi_end_io */
|
||||||
@ -640,6 +635,7 @@ next_page:
|
|||||||
bl_end_io_write, par);
|
bl_end_io_write, par);
|
||||||
if (IS_ERR(bio)) {
|
if (IS_ERR(bio)) {
|
||||||
wdata->pnfs_error = PTR_ERR(bio);
|
wdata->pnfs_error = PTR_ERR(bio);
|
||||||
|
bio = NULL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
isect += PAGE_CACHE_SECTORS;
|
isect += PAGE_CACHE_SECTORS;
|
||||||
@ -805,7 +801,7 @@ nfs4_blk_get_deviceinfo(struct nfs_server *server, const struct nfs_fh *fh,
|
|||||||
struct nfs4_deviceid *d_id)
|
struct nfs4_deviceid *d_id)
|
||||||
{
|
{
|
||||||
struct pnfs_device *dev;
|
struct pnfs_device *dev;
|
||||||
struct pnfs_block_dev *rv = NULL;
|
struct pnfs_block_dev *rv;
|
||||||
u32 max_resp_sz;
|
u32 max_resp_sz;
|
||||||
int max_pages;
|
int max_pages;
|
||||||
struct page **pages = NULL;
|
struct page **pages = NULL;
|
||||||
@ -823,18 +819,20 @@ nfs4_blk_get_deviceinfo(struct nfs_server *server, const struct nfs_fh *fh,
|
|||||||
dev = kmalloc(sizeof(*dev), GFP_NOFS);
|
dev = kmalloc(sizeof(*dev), GFP_NOFS);
|
||||||
if (!dev) {
|
if (!dev) {
|
||||||
dprintk("%s kmalloc failed\n", __func__);
|
dprintk("%s kmalloc failed\n", __func__);
|
||||||
return NULL;
|
return ERR_PTR(-ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
pages = kzalloc(max_pages * sizeof(struct page *), GFP_NOFS);
|
pages = kzalloc(max_pages * sizeof(struct page *), GFP_NOFS);
|
||||||
if (pages == NULL) {
|
if (pages == NULL) {
|
||||||
kfree(dev);
|
kfree(dev);
|
||||||
return NULL;
|
return ERR_PTR(-ENOMEM);
|
||||||
}
|
}
|
||||||
for (i = 0; i < max_pages; i++) {
|
for (i = 0; i < max_pages; i++) {
|
||||||
pages[i] = alloc_page(GFP_NOFS);
|
pages[i] = alloc_page(GFP_NOFS);
|
||||||
if (!pages[i])
|
if (!pages[i]) {
|
||||||
|
rv = ERR_PTR(-ENOMEM);
|
||||||
goto out_free;
|
goto out_free;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&dev->dev_id, d_id, sizeof(*d_id));
|
memcpy(&dev->dev_id, d_id, sizeof(*d_id));
|
||||||
@ -847,8 +845,10 @@ nfs4_blk_get_deviceinfo(struct nfs_server *server, const struct nfs_fh *fh,
|
|||||||
dprintk("%s: dev_id: %s\n", __func__, dev->dev_id.data);
|
dprintk("%s: dev_id: %s\n", __func__, dev->dev_id.data);
|
||||||
rc = nfs4_proc_getdeviceinfo(server, dev);
|
rc = nfs4_proc_getdeviceinfo(server, dev);
|
||||||
dprintk("%s getdevice info returns %d\n", __func__, rc);
|
dprintk("%s getdevice info returns %d\n", __func__, rc);
|
||||||
if (rc)
|
if (rc) {
|
||||||
|
rv = ERR_PTR(rc);
|
||||||
goto out_free;
|
goto out_free;
|
||||||
|
}
|
||||||
|
|
||||||
rv = nfs4_blk_decode_device(server, dev);
|
rv = nfs4_blk_decode_device(server, dev);
|
||||||
out_free:
|
out_free:
|
||||||
@ -866,7 +866,7 @@ bl_set_layoutdriver(struct nfs_server *server, const struct nfs_fh *fh)
|
|||||||
struct pnfs_devicelist *dlist = NULL;
|
struct pnfs_devicelist *dlist = NULL;
|
||||||
struct pnfs_block_dev *bdev;
|
struct pnfs_block_dev *bdev;
|
||||||
LIST_HEAD(block_disklist);
|
LIST_HEAD(block_disklist);
|
||||||
int status = 0, i;
|
int status, i;
|
||||||
|
|
||||||
dprintk("%s enter\n", __func__);
|
dprintk("%s enter\n", __func__);
|
||||||
|
|
||||||
@ -898,8 +898,8 @@ bl_set_layoutdriver(struct nfs_server *server, const struct nfs_fh *fh)
|
|||||||
for (i = 0; i < dlist->num_devs; i++) {
|
for (i = 0; i < dlist->num_devs; i++) {
|
||||||
bdev = nfs4_blk_get_deviceinfo(server, fh,
|
bdev = nfs4_blk_get_deviceinfo(server, fh,
|
||||||
&dlist->dev_id[i]);
|
&dlist->dev_id[i]);
|
||||||
if (!bdev) {
|
if (IS_ERR(bdev)) {
|
||||||
status = -ENODEV;
|
status = PTR_ERR(bdev);
|
||||||
goto out_error;
|
goto out_error;
|
||||||
}
|
}
|
||||||
spin_lock(&b_mt_id->bm_lock);
|
spin_lock(&b_mt_id->bm_lock);
|
||||||
@ -960,7 +960,7 @@ static struct pnfs_layoutdriver_type blocklayout_type = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct rpc_pipe_ops bl_upcall_ops = {
|
static const struct rpc_pipe_ops bl_upcall_ops = {
|
||||||
.upcall = bl_pipe_upcall,
|
.upcall = rpc_pipe_generic_upcall,
|
||||||
.downcall = bl_pipe_downcall,
|
.downcall = bl_pipe_downcall,
|
||||||
.destroy_msg = bl_pipe_destroy_msg,
|
.destroy_msg = bl_pipe_destroy_msg,
|
||||||
};
|
};
|
||||||
@ -989,17 +989,20 @@ static int __init nfs4blocklayout_init(void)
|
|||||||
mnt,
|
mnt,
|
||||||
NFS_PIPE_DIRNAME, 0, &path);
|
NFS_PIPE_DIRNAME, 0, &path);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_remove;
|
goto out_putrpc;
|
||||||
|
|
||||||
bl_device_pipe = rpc_mkpipe(path.dentry, "blocklayout", NULL,
|
bl_device_pipe = rpc_mkpipe(path.dentry, "blocklayout", NULL,
|
||||||
&bl_upcall_ops, 0);
|
&bl_upcall_ops, 0);
|
||||||
|
path_put(&path);
|
||||||
if (IS_ERR(bl_device_pipe)) {
|
if (IS_ERR(bl_device_pipe)) {
|
||||||
ret = PTR_ERR(bl_device_pipe);
|
ret = PTR_ERR(bl_device_pipe);
|
||||||
goto out_remove;
|
goto out_putrpc;
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
out_putrpc:
|
||||||
|
rpc_put_mount();
|
||||||
out_remove:
|
out_remove:
|
||||||
pnfs_unregister_layoutdriver(&blocklayout_type);
|
pnfs_unregister_layoutdriver(&blocklayout_type);
|
||||||
return ret;
|
return ret;
|
||||||
@ -1012,6 +1015,7 @@ static void __exit nfs4blocklayout_exit(void)
|
|||||||
|
|
||||||
pnfs_unregister_layoutdriver(&blocklayout_type);
|
pnfs_unregister_layoutdriver(&blocklayout_type);
|
||||||
rpc_unlink(bl_device_pipe);
|
rpc_unlink(bl_device_pipe);
|
||||||
|
rpc_put_mount();
|
||||||
}
|
}
|
||||||
|
|
||||||
MODULE_ALIAS("nfs-layouttype4-3");
|
MODULE_ALIAS("nfs-layouttype4-3");
|
||||||
|
@ -150,7 +150,7 @@ BLK_LSEG2EXT(struct pnfs_layout_segment *lseg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct bl_dev_msg {
|
struct bl_dev_msg {
|
||||||
int status;
|
int32_t status;
|
||||||
uint32_t major, minor;
|
uint32_t major, minor;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -169,8 +169,6 @@ extern wait_queue_head_t bl_wq;
|
|||||||
#define BL_DEVICE_REQUEST_ERR 0x2 /* User level process fails */
|
#define BL_DEVICE_REQUEST_ERR 0x2 /* User level process fails */
|
||||||
|
|
||||||
/* blocklayoutdev.c */
|
/* blocklayoutdev.c */
|
||||||
ssize_t bl_pipe_upcall(struct file *, struct rpc_pipe_msg *,
|
|
||||||
char __user *, size_t);
|
|
||||||
ssize_t bl_pipe_downcall(struct file *, const char __user *, size_t);
|
ssize_t bl_pipe_downcall(struct file *, const char __user *, size_t);
|
||||||
void bl_pipe_destroy_msg(struct rpc_pipe_msg *);
|
void bl_pipe_destroy_msg(struct rpc_pipe_msg *);
|
||||||
struct block_device *nfs4_blkdev_get(dev_t dev);
|
struct block_device *nfs4_blkdev_get(dev_t dev);
|
||||||
|
@ -79,28 +79,6 @@ int nfs4_blkdev_put(struct block_device *bdev)
|
|||||||
return blkdev_put(bdev, FMODE_READ);
|
return blkdev_put(bdev, FMODE_READ);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Shouldn't there be a rpc_generic_upcall() to do this for us?
|
|
||||||
*/
|
|
||||||
ssize_t bl_pipe_upcall(struct file *filp, struct rpc_pipe_msg *msg,
|
|
||||||
char __user *dst, size_t buflen)
|
|
||||||
{
|
|
||||||
char *data = (char *)msg->data + msg->copied;
|
|
||||||
size_t mlen = min(msg->len - msg->copied, buflen);
|
|
||||||
unsigned long left;
|
|
||||||
|
|
||||||
left = copy_to_user(dst, data, mlen);
|
|
||||||
if (left == mlen) {
|
|
||||||
msg->errno = -EFAULT;
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
mlen -= left;
|
|
||||||
msg->copied += mlen;
|
|
||||||
msg->errno = 0;
|
|
||||||
return mlen;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct bl_dev_msg bl_mount_reply;
|
static struct bl_dev_msg bl_mount_reply;
|
||||||
|
|
||||||
ssize_t bl_pipe_downcall(struct file *filp, const char __user *src,
|
ssize_t bl_pipe_downcall(struct file *filp, const char __user *src,
|
||||||
@ -131,7 +109,7 @@ struct pnfs_block_dev *
|
|||||||
nfs4_blk_decode_device(struct nfs_server *server,
|
nfs4_blk_decode_device(struct nfs_server *server,
|
||||||
struct pnfs_device *dev)
|
struct pnfs_device *dev)
|
||||||
{
|
{
|
||||||
struct pnfs_block_dev *rv = NULL;
|
struct pnfs_block_dev *rv;
|
||||||
struct block_device *bd = NULL;
|
struct block_device *bd = NULL;
|
||||||
struct rpc_pipe_msg msg;
|
struct rpc_pipe_msg msg;
|
||||||
struct bl_msg_hdr bl_msg = {
|
struct bl_msg_hdr bl_msg = {
|
||||||
@ -141,7 +119,7 @@ nfs4_blk_decode_device(struct nfs_server *server,
|
|||||||
uint8_t *dataptr;
|
uint8_t *dataptr;
|
||||||
DECLARE_WAITQUEUE(wq, current);
|
DECLARE_WAITQUEUE(wq, current);
|
||||||
struct bl_dev_msg *reply = &bl_mount_reply;
|
struct bl_dev_msg *reply = &bl_mount_reply;
|
||||||
int offset, len, i;
|
int offset, len, i, rc;
|
||||||
|
|
||||||
dprintk("%s CREATING PIPEFS MESSAGE\n", __func__);
|
dprintk("%s CREATING PIPEFS MESSAGE\n", __func__);
|
||||||
dprintk("%s: deviceid: %s, mincount: %d\n", __func__, dev->dev_id.data,
|
dprintk("%s: deviceid: %s, mincount: %d\n", __func__, dev->dev_id.data,
|
||||||
@ -168,8 +146,10 @@ nfs4_blk_decode_device(struct nfs_server *server,
|
|||||||
|
|
||||||
dprintk("%s CALLING USERSPACE DAEMON\n", __func__);
|
dprintk("%s CALLING USERSPACE DAEMON\n", __func__);
|
||||||
add_wait_queue(&bl_wq, &wq);
|
add_wait_queue(&bl_wq, &wq);
|
||||||
if (rpc_queue_upcall(bl_device_pipe->d_inode, &msg) < 0) {
|
rc = rpc_queue_upcall(bl_device_pipe->d_inode, &msg);
|
||||||
|
if (rc < 0) {
|
||||||
remove_wait_queue(&bl_wq, &wq);
|
remove_wait_queue(&bl_wq, &wq);
|
||||||
|
rv = ERR_PTR(rc);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,8 +167,9 @@ nfs4_blk_decode_device(struct nfs_server *server,
|
|||||||
|
|
||||||
bd = nfs4_blkdev_get(MKDEV(reply->major, reply->minor));
|
bd = nfs4_blkdev_get(MKDEV(reply->major, reply->minor));
|
||||||
if (IS_ERR(bd)) {
|
if (IS_ERR(bd)) {
|
||||||
dprintk("%s failed to open device : %ld\n",
|
rc = PTR_ERR(bd);
|
||||||
__func__, PTR_ERR(bd));
|
dprintk("%s failed to open device : %d\n", __func__, rc);
|
||||||
|
rv = ERR_PTR(rc);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1868,6 +1868,10 @@ static int nfs_server_list_show(struct seq_file *m, void *v)
|
|||||||
/* display one transport per line on subsequent lines */
|
/* display one transport per line on subsequent lines */
|
||||||
clp = list_entry(v, struct nfs_client, cl_share_link);
|
clp = list_entry(v, struct nfs_client, cl_share_link);
|
||||||
|
|
||||||
|
/* Check if the client is initialized */
|
||||||
|
if (clp->cl_cons_state != NFS_CS_READY)
|
||||||
|
return 0;
|
||||||
|
|
||||||
seq_printf(m, "v%u %s %s %3d %s\n",
|
seq_printf(m, "v%u %s %s %3d %s\n",
|
||||||
clp->rpc_ops->version,
|
clp->rpc_ops->version,
|
||||||
rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_ADDR),
|
rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_ADDR),
|
||||||
|
@ -240,7 +240,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
|
|||||||
sizeof(delegation->stateid.data));
|
sizeof(delegation->stateid.data));
|
||||||
delegation->type = res->delegation_type;
|
delegation->type = res->delegation_type;
|
||||||
delegation->maxsize = res->maxsize;
|
delegation->maxsize = res->maxsize;
|
||||||
delegation->change_attr = nfsi->change_attr;
|
delegation->change_attr = inode->i_version;
|
||||||
delegation->cred = get_rpccred(cred);
|
delegation->cred = get_rpccred(cred);
|
||||||
delegation->inode = inode;
|
delegation->inode = inode;
|
||||||
delegation->flags = 1<<NFS_DELEGATION_REFERENCED;
|
delegation->flags = 1<<NFS_DELEGATION_REFERENCED;
|
||||||
|
@ -212,7 +212,7 @@ static uint16_t nfs_fscache_inode_get_aux(const void *cookie_netfs_data,
|
|||||||
auxdata.ctime = nfsi->vfs_inode.i_ctime;
|
auxdata.ctime = nfsi->vfs_inode.i_ctime;
|
||||||
|
|
||||||
if (NFS_SERVER(&nfsi->vfs_inode)->nfs_client->rpc_ops->version == 4)
|
if (NFS_SERVER(&nfsi->vfs_inode)->nfs_client->rpc_ops->version == 4)
|
||||||
auxdata.change_attr = nfsi->change_attr;
|
auxdata.change_attr = nfsi->vfs_inode.i_version;
|
||||||
|
|
||||||
if (bufmax > sizeof(auxdata))
|
if (bufmax > sizeof(auxdata))
|
||||||
bufmax = sizeof(auxdata);
|
bufmax = sizeof(auxdata);
|
||||||
@ -244,7 +244,7 @@ enum fscache_checkaux nfs_fscache_inode_check_aux(void *cookie_netfs_data,
|
|||||||
auxdata.ctime = nfsi->vfs_inode.i_ctime;
|
auxdata.ctime = nfsi->vfs_inode.i_ctime;
|
||||||
|
|
||||||
if (NFS_SERVER(&nfsi->vfs_inode)->nfs_client->rpc_ops->version == 4)
|
if (NFS_SERVER(&nfsi->vfs_inode)->nfs_client->rpc_ops->version == 4)
|
||||||
auxdata.change_attr = nfsi->change_attr;
|
auxdata.change_attr = nfsi->vfs_inode.i_version;
|
||||||
|
|
||||||
if (memcmp(data, &auxdata, datalen) != 0)
|
if (memcmp(data, &auxdata, datalen) != 0)
|
||||||
return FSCACHE_CHECKAUX_OBSOLETE;
|
return FSCACHE_CHECKAUX_OBSOLETE;
|
||||||
|
@ -336,8 +336,6 @@ struct idmap {
|
|||||||
struct idmap_hashtable idmap_group_hash;
|
struct idmap_hashtable idmap_group_hash;
|
||||||
};
|
};
|
||||||
|
|
||||||
static ssize_t idmap_pipe_upcall(struct file *, struct rpc_pipe_msg *,
|
|
||||||
char __user *, size_t);
|
|
||||||
static ssize_t idmap_pipe_downcall(struct file *, const char __user *,
|
static ssize_t idmap_pipe_downcall(struct file *, const char __user *,
|
||||||
size_t);
|
size_t);
|
||||||
static void idmap_pipe_destroy_msg(struct rpc_pipe_msg *);
|
static void idmap_pipe_destroy_msg(struct rpc_pipe_msg *);
|
||||||
@ -345,7 +343,7 @@ static void idmap_pipe_destroy_msg(struct rpc_pipe_msg *);
|
|||||||
static unsigned int fnvhash32(const void *, size_t);
|
static unsigned int fnvhash32(const void *, size_t);
|
||||||
|
|
||||||
static const struct rpc_pipe_ops idmap_upcall_ops = {
|
static const struct rpc_pipe_ops idmap_upcall_ops = {
|
||||||
.upcall = idmap_pipe_upcall,
|
.upcall = rpc_pipe_generic_upcall,
|
||||||
.downcall = idmap_pipe_downcall,
|
.downcall = idmap_pipe_downcall,
|
||||||
.destroy_msg = idmap_pipe_destroy_msg,
|
.destroy_msg = idmap_pipe_destroy_msg,
|
||||||
};
|
};
|
||||||
@ -595,27 +593,6 @@ nfs_idmap_name(struct idmap *idmap, struct idmap_hashtable *h,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* RPC pipefs upcall/downcall routines */
|
|
||||||
static ssize_t
|
|
||||||
idmap_pipe_upcall(struct file *filp, struct rpc_pipe_msg *msg,
|
|
||||||
char __user *dst, size_t buflen)
|
|
||||||
{
|
|
||||||
char *data = (char *)msg->data + msg->copied;
|
|
||||||
size_t mlen = min(msg->len, buflen);
|
|
||||||
unsigned long left;
|
|
||||||
|
|
||||||
left = copy_to_user(dst, data, mlen);
|
|
||||||
if (left == mlen) {
|
|
||||||
msg->errno = -EFAULT;
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
mlen -= left;
|
|
||||||
msg->copied += mlen;
|
|
||||||
msg->errno = 0;
|
|
||||||
return mlen;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
|
idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
|
||||||
{
|
{
|
||||||
|
@ -318,7 +318,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
|
|||||||
memset(&inode->i_atime, 0, sizeof(inode->i_atime));
|
memset(&inode->i_atime, 0, sizeof(inode->i_atime));
|
||||||
memset(&inode->i_mtime, 0, sizeof(inode->i_mtime));
|
memset(&inode->i_mtime, 0, sizeof(inode->i_mtime));
|
||||||
memset(&inode->i_ctime, 0, sizeof(inode->i_ctime));
|
memset(&inode->i_ctime, 0, sizeof(inode->i_ctime));
|
||||||
nfsi->change_attr = 0;
|
inode->i_version = 0;
|
||||||
inode->i_size = 0;
|
inode->i_size = 0;
|
||||||
inode->i_nlink = 0;
|
inode->i_nlink = 0;
|
||||||
inode->i_uid = -2;
|
inode->i_uid = -2;
|
||||||
@ -344,7 +344,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
|
|||||||
| NFS_INO_INVALID_ACCESS
|
| NFS_INO_INVALID_ACCESS
|
||||||
| NFS_INO_INVALID_ACL;
|
| NFS_INO_INVALID_ACL;
|
||||||
if (fattr->valid & NFS_ATTR_FATTR_CHANGE)
|
if (fattr->valid & NFS_ATTR_FATTR_CHANGE)
|
||||||
nfsi->change_attr = fattr->change_attr;
|
inode->i_version = fattr->change_attr;
|
||||||
else if (nfs_server_capable(inode, NFS_CAP_CHANGE_ATTR))
|
else if (nfs_server_capable(inode, NFS_CAP_CHANGE_ATTR))
|
||||||
nfsi->cache_validity |= NFS_INO_INVALID_ATTR
|
nfsi->cache_validity |= NFS_INO_INVALID_ATTR
|
||||||
| NFS_INO_INVALID_DATA;
|
| NFS_INO_INVALID_DATA;
|
||||||
@ -897,8 +897,8 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr
|
|||||||
|
|
||||||
if ((fattr->valid & NFS_ATTR_FATTR_PRECHANGE)
|
if ((fattr->valid & NFS_ATTR_FATTR_PRECHANGE)
|
||||||
&& (fattr->valid & NFS_ATTR_FATTR_CHANGE)
|
&& (fattr->valid & NFS_ATTR_FATTR_CHANGE)
|
||||||
&& nfsi->change_attr == fattr->pre_change_attr) {
|
&& inode->i_version == fattr->pre_change_attr) {
|
||||||
nfsi->change_attr = fattr->change_attr;
|
inode->i_version = fattr->change_attr;
|
||||||
if (S_ISDIR(inode->i_mode))
|
if (S_ISDIR(inode->i_mode))
|
||||||
nfsi->cache_validity |= NFS_INO_INVALID_DATA;
|
nfsi->cache_validity |= NFS_INO_INVALID_DATA;
|
||||||
ret |= NFS_INO_INVALID_ATTR;
|
ret |= NFS_INO_INVALID_ATTR;
|
||||||
@ -952,7 +952,7 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
|
|||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 &&
|
if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 &&
|
||||||
nfsi->change_attr != fattr->change_attr)
|
inode->i_version != fattr->change_attr)
|
||||||
invalid |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
|
invalid |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
|
||||||
|
|
||||||
/* Verify a few of the more important attributes */
|
/* Verify a few of the more important attributes */
|
||||||
@ -1163,7 +1163,7 @@ int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fa
|
|||||||
}
|
}
|
||||||
if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 &&
|
if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 &&
|
||||||
(fattr->valid & NFS_ATTR_FATTR_PRECHANGE) == 0) {
|
(fattr->valid & NFS_ATTR_FATTR_PRECHANGE) == 0) {
|
||||||
fattr->pre_change_attr = NFS_I(inode)->change_attr;
|
fattr->pre_change_attr = inode->i_version;
|
||||||
fattr->valid |= NFS_ATTR_FATTR_PRECHANGE;
|
fattr->valid |= NFS_ATTR_FATTR_PRECHANGE;
|
||||||
}
|
}
|
||||||
if ((fattr->valid & NFS_ATTR_FATTR_CTIME) != 0 &&
|
if ((fattr->valid & NFS_ATTR_FATTR_CTIME) != 0 &&
|
||||||
@ -1244,13 +1244,13 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
|
|||||||
|
|
||||||
/* More cache consistency checks */
|
/* More cache consistency checks */
|
||||||
if (fattr->valid & NFS_ATTR_FATTR_CHANGE) {
|
if (fattr->valid & NFS_ATTR_FATTR_CHANGE) {
|
||||||
if (nfsi->change_attr != fattr->change_attr) {
|
if (inode->i_version != fattr->change_attr) {
|
||||||
dprintk("NFS: change_attr change on server for file %s/%ld\n",
|
dprintk("NFS: change_attr change on server for file %s/%ld\n",
|
||||||
inode->i_sb->s_id, inode->i_ino);
|
inode->i_sb->s_id, inode->i_ino);
|
||||||
invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
|
invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
|
||||||
if (S_ISDIR(inode->i_mode))
|
if (S_ISDIR(inode->i_mode))
|
||||||
nfs_force_lookup_revalidate(inode);
|
nfs_force_lookup_revalidate(inode);
|
||||||
nfsi->change_attr = fattr->change_attr;
|
inode->i_version = fattr->change_attr;
|
||||||
}
|
}
|
||||||
} else if (server->caps & NFS_CAP_CHANGE_ATTR)
|
} else if (server->caps & NFS_CAP_CHANGE_ATTR)
|
||||||
invalid |= save_cache_validity;
|
invalid |= save_cache_validity;
|
||||||
|
@ -457,13 +457,3 @@ unsigned int nfs_page_array_len(unsigned int base, size_t len)
|
|||||||
PAGE_SIZE - 1) >> PAGE_SHIFT;
|
PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Helper for restarting RPC calls in the possible presence of NFSv4.1
|
|
||||||
* sessions.
|
|
||||||
*/
|
|
||||||
static inline int nfs_restart_rpc(struct rpc_task *task, const struct nfs_client *clp)
|
|
||||||
{
|
|
||||||
if (nfs4_has_session(clp))
|
|
||||||
return rpc_restart_call_prepare(task);
|
|
||||||
return rpc_restart_call(task);
|
|
||||||
}
|
|
||||||
|
@ -77,19 +77,6 @@ filelayout_get_dserver_offset(struct pnfs_layout_segment *lseg, loff_t offset)
|
|||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For data server errors we don't recover from */
|
|
||||||
static void
|
|
||||||
filelayout_set_lo_fail(struct pnfs_layout_segment *lseg)
|
|
||||||
{
|
|
||||||
if (lseg->pls_range.iomode == IOMODE_RW) {
|
|
||||||
dprintk("%s Setting layout IOMODE_RW fail bit\n", __func__);
|
|
||||||
set_bit(lo_fail_bit(IOMODE_RW), &lseg->pls_layout->plh_flags);
|
|
||||||
} else {
|
|
||||||
dprintk("%s Setting layout IOMODE_READ fail bit\n", __func__);
|
|
||||||
set_bit(lo_fail_bit(IOMODE_READ), &lseg->pls_layout->plh_flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int filelayout_async_handle_error(struct rpc_task *task,
|
static int filelayout_async_handle_error(struct rpc_task *task,
|
||||||
struct nfs4_state *state,
|
struct nfs4_state *state,
|
||||||
struct nfs_client *clp,
|
struct nfs_client *clp,
|
||||||
@ -135,7 +122,6 @@ static int filelayout_async_handle_error(struct rpc_task *task,
|
|||||||
static int filelayout_read_done_cb(struct rpc_task *task,
|
static int filelayout_read_done_cb(struct rpc_task *task,
|
||||||
struct nfs_read_data *data)
|
struct nfs_read_data *data)
|
||||||
{
|
{
|
||||||
struct nfs_client *clp = data->ds_clp;
|
|
||||||
int reset = 0;
|
int reset = 0;
|
||||||
|
|
||||||
dprintk("%s DS read\n", __func__);
|
dprintk("%s DS read\n", __func__);
|
||||||
@ -145,11 +131,10 @@ static int filelayout_read_done_cb(struct rpc_task *task,
|
|||||||
dprintk("%s calling restart ds_clp %p ds_clp->cl_session %p\n",
|
dprintk("%s calling restart ds_clp %p ds_clp->cl_session %p\n",
|
||||||
__func__, data->ds_clp, data->ds_clp->cl_session);
|
__func__, data->ds_clp, data->ds_clp->cl_session);
|
||||||
if (reset) {
|
if (reset) {
|
||||||
filelayout_set_lo_fail(data->lseg);
|
pnfs_set_lo_fail(data->lseg);
|
||||||
nfs4_reset_read(task, data);
|
nfs4_reset_read(task, data);
|
||||||
clp = NFS_SERVER(data->inode)->nfs_client;
|
|
||||||
}
|
}
|
||||||
nfs_restart_rpc(task, clp);
|
rpc_restart_call_prepare(task);
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,17 +201,13 @@ static int filelayout_write_done_cb(struct rpc_task *task,
|
|||||||
|
|
||||||
if (filelayout_async_handle_error(task, data->args.context->state,
|
if (filelayout_async_handle_error(task, data->args.context->state,
|
||||||
data->ds_clp, &reset) == -EAGAIN) {
|
data->ds_clp, &reset) == -EAGAIN) {
|
||||||
struct nfs_client *clp;
|
|
||||||
|
|
||||||
dprintk("%s calling restart ds_clp %p ds_clp->cl_session %p\n",
|
dprintk("%s calling restart ds_clp %p ds_clp->cl_session %p\n",
|
||||||
__func__, data->ds_clp, data->ds_clp->cl_session);
|
__func__, data->ds_clp, data->ds_clp->cl_session);
|
||||||
if (reset) {
|
if (reset) {
|
||||||
filelayout_set_lo_fail(data->lseg);
|
pnfs_set_lo_fail(data->lseg);
|
||||||
nfs4_reset_write(task, data);
|
nfs4_reset_write(task, data);
|
||||||
clp = NFS_SERVER(data->inode)->nfs_client;
|
}
|
||||||
} else
|
rpc_restart_call_prepare(task);
|
||||||
clp = data->ds_clp;
|
|
||||||
nfs_restart_rpc(task, clp);
|
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,9 +237,9 @@ static int filelayout_commit_done_cb(struct rpc_task *task,
|
|||||||
__func__, data->ds_clp, data->ds_clp->cl_session);
|
__func__, data->ds_clp, data->ds_clp->cl_session);
|
||||||
if (reset) {
|
if (reset) {
|
||||||
prepare_to_resend_writes(data);
|
prepare_to_resend_writes(data);
|
||||||
filelayout_set_lo_fail(data->lseg);
|
pnfs_set_lo_fail(data->lseg);
|
||||||
} else
|
} else
|
||||||
nfs_restart_rpc(task, data->ds_clp);
|
rpc_restart_call_prepare(task);
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,9 +73,6 @@ static int _nfs4_proc_open(struct nfs4_opendata *data);
|
|||||||
static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
|
static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
|
||||||
static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
|
static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
|
||||||
static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *);
|
static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *);
|
||||||
static int _nfs4_proc_lookup(struct rpc_clnt *client, struct inode *dir,
|
|
||||||
const struct qstr *name, struct nfs_fh *fhandle,
|
|
||||||
struct nfs_fattr *fattr);
|
|
||||||
static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
|
static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
|
||||||
static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
|
static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
|
||||||
struct nfs_fattr *fattr, struct iattr *sattr,
|
struct nfs_fattr *fattr, struct iattr *sattr,
|
||||||
@ -753,9 +750,9 @@ static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo)
|
|||||||
|
|
||||||
spin_lock(&dir->i_lock);
|
spin_lock(&dir->i_lock);
|
||||||
nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_DATA;
|
nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_DATA;
|
||||||
if (!cinfo->atomic || cinfo->before != nfsi->change_attr)
|
if (!cinfo->atomic || cinfo->before != dir->i_version)
|
||||||
nfs_force_lookup_revalidate(dir);
|
nfs_force_lookup_revalidate(dir);
|
||||||
nfsi->change_attr = cinfo->after;
|
dir->i_version = cinfo->after;
|
||||||
spin_unlock(&dir->i_lock);
|
spin_unlock(&dir->i_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1596,8 +1593,14 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
|
|||||||
int status;
|
int status;
|
||||||
|
|
||||||
status = nfs4_run_open_task(data, 0);
|
status = nfs4_run_open_task(data, 0);
|
||||||
if (status != 0 || !data->rpc_done)
|
if (!data->rpc_done)
|
||||||
return status;
|
return status;
|
||||||
|
if (status != 0) {
|
||||||
|
if (status == -NFS4ERR_BADNAME &&
|
||||||
|
!(o_arg->open_flags & O_CREAT))
|
||||||
|
return -ENOENT;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
if (o_arg->open_flags & O_CREAT) {
|
if (o_arg->open_flags & O_CREAT) {
|
||||||
update_changeattr(dir, &o_res->cinfo);
|
update_changeattr(dir, &o_res->cinfo);
|
||||||
@ -2408,14 +2411,15 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _nfs4_proc_lookupfh(struct rpc_clnt *clnt, struct nfs_server *server,
|
static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir,
|
||||||
const struct nfs_fh *dirfh, const struct qstr *name,
|
const struct qstr *name, struct nfs_fh *fhandle,
|
||||||
struct nfs_fh *fhandle, struct nfs_fattr *fattr)
|
struct nfs_fattr *fattr)
|
||||||
{
|
{
|
||||||
|
struct nfs_server *server = NFS_SERVER(dir);
|
||||||
int status;
|
int status;
|
||||||
struct nfs4_lookup_arg args = {
|
struct nfs4_lookup_arg args = {
|
||||||
.bitmask = server->attr_bitmask,
|
.bitmask = server->attr_bitmask,
|
||||||
.dir_fh = dirfh,
|
.dir_fh = NFS_FH(dir),
|
||||||
.name = name,
|
.name = name,
|
||||||
};
|
};
|
||||||
struct nfs4_lookup_res res = {
|
struct nfs4_lookup_res res = {
|
||||||
@ -2431,40 +2435,8 @@ static int _nfs4_proc_lookupfh(struct rpc_clnt *clnt, struct nfs_server *server,
|
|||||||
|
|
||||||
nfs_fattr_init(fattr);
|
nfs_fattr_init(fattr);
|
||||||
|
|
||||||
dprintk("NFS call lookupfh %s\n", name->name);
|
|
||||||
status = nfs4_call_sync(clnt, server, &msg, &args.seq_args, &res.seq_res, 0);
|
|
||||||
dprintk("NFS reply lookupfh: %d\n", status);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nfs4_proc_lookupfh(struct nfs_server *server, struct nfs_fh *dirfh,
|
|
||||||
struct qstr *name, struct nfs_fh *fhandle,
|
|
||||||
struct nfs_fattr *fattr)
|
|
||||||
{
|
|
||||||
struct nfs4_exception exception = { };
|
|
||||||
int err;
|
|
||||||
do {
|
|
||||||
err = _nfs4_proc_lookupfh(server->client, server, dirfh, name, fhandle, fattr);
|
|
||||||
/* FIXME: !!!! */
|
|
||||||
if (err == -NFS4ERR_MOVED) {
|
|
||||||
err = -EREMOTE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
err = nfs4_handle_exception(server, err, &exception);
|
|
||||||
} while (exception.retry);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir,
|
|
||||||
const struct qstr *name, struct nfs_fh *fhandle,
|
|
||||||
struct nfs_fattr *fattr)
|
|
||||||
{
|
|
||||||
int status;
|
|
||||||
|
|
||||||
dprintk("NFS call lookup %s\n", name->name);
|
dprintk("NFS call lookup %s\n", name->name);
|
||||||
status = _nfs4_proc_lookupfh(clnt, NFS_SERVER(dir), NFS_FH(dir), name, fhandle, fattr);
|
status = nfs4_call_sync(clnt, server, &msg, &args.seq_args, &res.seq_res, 0);
|
||||||
if (status == -NFS4ERR_MOVED)
|
|
||||||
status = nfs4_get_referral(dir, name, fattr, fhandle);
|
|
||||||
dprintk("NFS reply lookup: %d\n", status);
|
dprintk("NFS reply lookup: %d\n", status);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -2485,11 +2457,20 @@ static int nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir, struct qst
|
|||||||
struct nfs4_exception exception = { };
|
struct nfs4_exception exception = { };
|
||||||
int err;
|
int err;
|
||||||
do {
|
do {
|
||||||
err = nfs4_handle_exception(NFS_SERVER(dir),
|
int status;
|
||||||
_nfs4_proc_lookup(clnt, dir, name, fhandle, fattr),
|
|
||||||
&exception);
|
status = _nfs4_proc_lookup(clnt, dir, name, fhandle, fattr);
|
||||||
if (err == -EPERM)
|
switch (status) {
|
||||||
|
case -NFS4ERR_BADNAME:
|
||||||
|
return -ENOENT;
|
||||||
|
case -NFS4ERR_MOVED:
|
||||||
|
err = nfs4_get_referral(dir, name, fattr, fhandle);
|
||||||
|
break;
|
||||||
|
case -NFS4ERR_WRONGSEC:
|
||||||
nfs_fixup_secinfo_attributes(fattr, fhandle);
|
nfs_fixup_secinfo_attributes(fattr, fhandle);
|
||||||
|
}
|
||||||
|
err = nfs4_handle_exception(NFS_SERVER(dir),
|
||||||
|
status, &exception);
|
||||||
} while (exception.retry);
|
} while (exception.retry);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -3210,7 +3191,7 @@ static int nfs4_read_done_cb(struct rpc_task *task, struct nfs_read_data *data)
|
|||||||
struct nfs_server *server = NFS_SERVER(data->inode);
|
struct nfs_server *server = NFS_SERVER(data->inode);
|
||||||
|
|
||||||
if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) {
|
if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) {
|
||||||
nfs_restart_rpc(task, server->nfs_client);
|
rpc_restart_call_prepare(task);
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3260,7 +3241,7 @@ static int nfs4_write_done_cb(struct rpc_task *task, struct nfs_write_data *data
|
|||||||
struct inode *inode = data->inode;
|
struct inode *inode = data->inode;
|
||||||
|
|
||||||
if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) {
|
if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) {
|
||||||
nfs_restart_rpc(task, NFS_SERVER(inode)->nfs_client);
|
rpc_restart_call_prepare(task);
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
if (task->tk_status >= 0) {
|
if (task->tk_status >= 0) {
|
||||||
@ -3317,7 +3298,7 @@ static int nfs4_commit_done_cb(struct rpc_task *task, struct nfs_write_data *dat
|
|||||||
struct inode *inode = data->inode;
|
struct inode *inode = data->inode;
|
||||||
|
|
||||||
if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) {
|
if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) {
|
||||||
nfs_restart_rpc(task, NFS_SERVER(inode)->nfs_client);
|
rpc_restart_call_prepare(task);
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
nfs_refresh_inode(inode, data->res.fattr);
|
nfs_refresh_inode(inode, data->res.fattr);
|
||||||
@ -3857,7 +3838,7 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
|
|||||||
default:
|
default:
|
||||||
if (nfs4_async_handle_error(task, data->res.server, NULL) ==
|
if (nfs4_async_handle_error(task, data->res.server, NULL) ==
|
||||||
-EAGAIN) {
|
-EAGAIN) {
|
||||||
nfs_restart_rpc(task, data->res.server->nfs_client);
|
rpc_restart_call_prepare(task);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4111,8 +4092,7 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN)
|
if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN)
|
||||||
nfs_restart_rpc(task,
|
rpc_restart_call_prepare(task);
|
||||||
calldata->server->nfs_client);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4945,7 +4925,7 @@ static void nfs4_get_lease_time_done(struct rpc_task *task, void *calldata)
|
|||||||
task->tk_status = 0;
|
task->tk_status = 0;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case -NFS4ERR_RETRY_UNCACHED_REP:
|
case -NFS4ERR_RETRY_UNCACHED_REP:
|
||||||
nfs_restart_rpc(task, data->clp);
|
rpc_restart_call_prepare(task);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dprintk("<-- %s\n", __func__);
|
dprintk("<-- %s\n", __func__);
|
||||||
@ -5786,7 +5766,7 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
|
|||||||
|
|
||||||
server = NFS_SERVER(lrp->args.inode);
|
server = NFS_SERVER(lrp->args.inode);
|
||||||
if (nfs4_async_handle_error(task, server, NULL) == -EAGAIN) {
|
if (nfs4_async_handle_error(task, server, NULL) == -EAGAIN) {
|
||||||
nfs_restart_rpc(task, lrp->clp);
|
rpc_restart_call_prepare(task);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
spin_lock(&lo->plh_inode->i_lock);
|
spin_lock(&lo->plh_inode->i_lock);
|
||||||
@ -5957,7 +5937,7 @@ nfs4_layoutcommit_done(struct rpc_task *task, void *calldata)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (nfs4_async_handle_error(task, server, NULL) == -EAGAIN) {
|
if (nfs4_async_handle_error(task, server, NULL) == -EAGAIN) {
|
||||||
nfs_restart_rpc(task, server->nfs_client);
|
rpc_restart_call_prepare(task);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6270,7 +6250,6 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
|
|||||||
.getroot = nfs4_proc_get_root,
|
.getroot = nfs4_proc_get_root,
|
||||||
.getattr = nfs4_proc_getattr,
|
.getattr = nfs4_proc_getattr,
|
||||||
.setattr = nfs4_proc_setattr,
|
.setattr = nfs4_proc_setattr,
|
||||||
.lookupfh = nfs4_proc_lookupfh,
|
|
||||||
.lookup = nfs4_proc_lookup,
|
.lookup = nfs4_proc_lookup,
|
||||||
.access = nfs4_proc_access,
|
.access = nfs4_proc_access,
|
||||||
.readlink = nfs4_proc_readlink,
|
.readlink = nfs4_proc_readlink,
|
||||||
|
@ -1168,23 +1168,17 @@ EXPORT_SYMBOL_GPL(pnfs_generic_pg_test);
|
|||||||
/*
|
/*
|
||||||
* Called by non rpc-based layout drivers
|
* Called by non rpc-based layout drivers
|
||||||
*/
|
*/
|
||||||
int
|
void pnfs_ld_write_done(struct nfs_write_data *data)
|
||||||
pnfs_ld_write_done(struct nfs_write_data *data)
|
|
||||||
{
|
{
|
||||||
int status;
|
if (likely(!data->pnfs_error)) {
|
||||||
|
|
||||||
if (!data->pnfs_error) {
|
|
||||||
pnfs_set_layoutcommit(data);
|
pnfs_set_layoutcommit(data);
|
||||||
data->mds_ops->rpc_call_done(&data->task, data);
|
data->mds_ops->rpc_call_done(&data->task, data);
|
||||||
data->mds_ops->rpc_release(data);
|
} else {
|
||||||
return 0;
|
put_lseg(data->lseg);
|
||||||
|
data->lseg = NULL;
|
||||||
|
dprintk("pnfs write error = %d\n", data->pnfs_error);
|
||||||
}
|
}
|
||||||
|
data->mds_ops->rpc_release(data);
|
||||||
dprintk("%s: pnfs_error=%d, retry via MDS\n", __func__,
|
|
||||||
data->pnfs_error);
|
|
||||||
status = nfs_initiate_write(data, NFS_CLIENT(data->inode),
|
|
||||||
data->mds_ops, NFS_FILE_SYNC);
|
|
||||||
return status ? : -EAGAIN;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(pnfs_ld_write_done);
|
EXPORT_SYMBOL_GPL(pnfs_ld_write_done);
|
||||||
|
|
||||||
@ -1268,23 +1262,17 @@ EXPORT_SYMBOL_GPL(pnfs_generic_pg_writepages);
|
|||||||
/*
|
/*
|
||||||
* Called by non rpc-based layout drivers
|
* Called by non rpc-based layout drivers
|
||||||
*/
|
*/
|
||||||
int
|
void pnfs_ld_read_done(struct nfs_read_data *data)
|
||||||
pnfs_ld_read_done(struct nfs_read_data *data)
|
|
||||||
{
|
{
|
||||||
int status;
|
if (likely(!data->pnfs_error)) {
|
||||||
|
|
||||||
if (!data->pnfs_error) {
|
|
||||||
__nfs4_read_done_cb(data);
|
__nfs4_read_done_cb(data);
|
||||||
data->mds_ops->rpc_call_done(&data->task, data);
|
data->mds_ops->rpc_call_done(&data->task, data);
|
||||||
data->mds_ops->rpc_release(data);
|
} else {
|
||||||
return 0;
|
put_lseg(data->lseg);
|
||||||
|
data->lseg = NULL;
|
||||||
|
dprintk("pnfs write error = %d\n", data->pnfs_error);
|
||||||
}
|
}
|
||||||
|
data->mds_ops->rpc_release(data);
|
||||||
dprintk("%s: pnfs_error=%d, retry via MDS\n", __func__,
|
|
||||||
data->pnfs_error);
|
|
||||||
status = nfs_initiate_read(data, NFS_CLIENT(data->inode),
|
|
||||||
data->mds_ops);
|
|
||||||
return status ? : -EAGAIN;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(pnfs_ld_read_done);
|
EXPORT_SYMBOL_GPL(pnfs_ld_read_done);
|
||||||
|
|
||||||
@ -1381,6 +1369,18 @@ static void pnfs_list_write_lseg(struct inode *inode, struct list_head *listp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pnfs_set_lo_fail(struct pnfs_layout_segment *lseg)
|
||||||
|
{
|
||||||
|
if (lseg->pls_range.iomode == IOMODE_RW) {
|
||||||
|
dprintk("%s Setting layout IOMODE_RW fail bit\n", __func__);
|
||||||
|
set_bit(lo_fail_bit(IOMODE_RW), &lseg->pls_layout->plh_flags);
|
||||||
|
} else {
|
||||||
|
dprintk("%s Setting layout IOMODE_READ fail bit\n", __func__);
|
||||||
|
set_bit(lo_fail_bit(IOMODE_READ), &lseg->pls_layout->plh_flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(pnfs_set_lo_fail);
|
||||||
|
|
||||||
void
|
void
|
||||||
pnfs_set_layoutcommit(struct nfs_write_data *wdata)
|
pnfs_set_layoutcommit(struct nfs_write_data *wdata)
|
||||||
{
|
{
|
||||||
|
@ -178,6 +178,7 @@ int pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc);
|
|||||||
void pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *, struct nfs_page *);
|
void pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *, struct nfs_page *);
|
||||||
int pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc);
|
int pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc);
|
||||||
bool pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, struct nfs_page *req);
|
bool pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, struct nfs_page *req);
|
||||||
|
void pnfs_set_lo_fail(struct pnfs_layout_segment *lseg);
|
||||||
int pnfs_layout_process(struct nfs4_layoutget *lgp);
|
int pnfs_layout_process(struct nfs4_layoutget *lgp);
|
||||||
void pnfs_free_lseg_list(struct list_head *tmp_list);
|
void pnfs_free_lseg_list(struct list_head *tmp_list);
|
||||||
void pnfs_destroy_layout(struct nfs_inode *);
|
void pnfs_destroy_layout(struct nfs_inode *);
|
||||||
@ -200,8 +201,8 @@ void pnfs_set_layoutcommit(struct nfs_write_data *wdata);
|
|||||||
void pnfs_cleanup_layoutcommit(struct nfs4_layoutcommit_data *data);
|
void pnfs_cleanup_layoutcommit(struct nfs4_layoutcommit_data *data);
|
||||||
int pnfs_layoutcommit_inode(struct inode *inode, bool sync);
|
int pnfs_layoutcommit_inode(struct inode *inode, bool sync);
|
||||||
int _pnfs_return_layout(struct inode *);
|
int _pnfs_return_layout(struct inode *);
|
||||||
int pnfs_ld_write_done(struct nfs_write_data *);
|
void pnfs_ld_write_done(struct nfs_write_data *);
|
||||||
int pnfs_ld_read_done(struct nfs_read_data *);
|
void pnfs_ld_read_done(struct nfs_read_data *);
|
||||||
struct pnfs_layout_segment *pnfs_update_layout(struct inode *ino,
|
struct pnfs_layout_segment *pnfs_update_layout(struct inode *ino,
|
||||||
struct nfs_open_context *ctx,
|
struct nfs_open_context *ctx,
|
||||||
loff_t pos,
|
loff_t pos,
|
||||||
|
@ -35,16 +35,13 @@ static const struct rpc_call_ops nfs_read_partial_ops;
|
|||||||
static const struct rpc_call_ops nfs_read_full_ops;
|
static const struct rpc_call_ops nfs_read_full_ops;
|
||||||
|
|
||||||
static struct kmem_cache *nfs_rdata_cachep;
|
static struct kmem_cache *nfs_rdata_cachep;
|
||||||
static mempool_t *nfs_rdata_mempool;
|
|
||||||
|
|
||||||
#define MIN_POOL_READ (32)
|
|
||||||
|
|
||||||
struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount)
|
struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount)
|
||||||
{
|
{
|
||||||
struct nfs_read_data *p = mempool_alloc(nfs_rdata_mempool, GFP_KERNEL);
|
struct nfs_read_data *p;
|
||||||
|
|
||||||
|
p = kmem_cache_zalloc(nfs_rdata_cachep, GFP_KERNEL);
|
||||||
if (p) {
|
if (p) {
|
||||||
memset(p, 0, sizeof(*p));
|
|
||||||
INIT_LIST_HEAD(&p->pages);
|
INIT_LIST_HEAD(&p->pages);
|
||||||
p->npages = pagecount;
|
p->npages = pagecount;
|
||||||
if (pagecount <= ARRAY_SIZE(p->page_array))
|
if (pagecount <= ARRAY_SIZE(p->page_array))
|
||||||
@ -52,7 +49,7 @@ struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount)
|
|||||||
else {
|
else {
|
||||||
p->pagevec = kcalloc(pagecount, sizeof(struct page *), GFP_KERNEL);
|
p->pagevec = kcalloc(pagecount, sizeof(struct page *), GFP_KERNEL);
|
||||||
if (!p->pagevec) {
|
if (!p->pagevec) {
|
||||||
mempool_free(p, nfs_rdata_mempool);
|
kmem_cache_free(nfs_rdata_cachep, p);
|
||||||
p = NULL;
|
p = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -64,7 +61,7 @@ void nfs_readdata_free(struct nfs_read_data *p)
|
|||||||
{
|
{
|
||||||
if (p && (p->pagevec != &p->page_array[0]))
|
if (p && (p->pagevec != &p->page_array[0]))
|
||||||
kfree(p->pagevec);
|
kfree(p->pagevec);
|
||||||
mempool_free(p, nfs_rdata_mempool);
|
kmem_cache_free(nfs_rdata_cachep, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nfs_readdata_release(struct nfs_read_data *rdata)
|
void nfs_readdata_release(struct nfs_read_data *rdata)
|
||||||
@ -276,7 +273,6 @@ nfs_async_read_error(struct list_head *head)
|
|||||||
while (!list_empty(head)) {
|
while (!list_empty(head)) {
|
||||||
req = nfs_list_entry(head->next);
|
req = nfs_list_entry(head->next);
|
||||||
nfs_list_remove_request(req);
|
nfs_list_remove_request(req);
|
||||||
SetPageError(req->wb_page);
|
|
||||||
nfs_readpage_release(req);
|
nfs_readpage_release(req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -322,7 +318,6 @@ static int nfs_pagein_multi(struct nfs_pageio_descriptor *desc, struct list_head
|
|||||||
offset += len;
|
offset += len;
|
||||||
} while(nbytes != 0);
|
} while(nbytes != 0);
|
||||||
atomic_set(&req->wb_complete, requests);
|
atomic_set(&req->wb_complete, requests);
|
||||||
ClearPageError(page);
|
|
||||||
desc->pg_rpc_callops = &nfs_read_partial_ops;
|
desc->pg_rpc_callops = &nfs_read_partial_ops;
|
||||||
return ret;
|
return ret;
|
||||||
out_bad:
|
out_bad:
|
||||||
@ -331,7 +326,6 @@ out_bad:
|
|||||||
list_del(&data->list);
|
list_del(&data->list);
|
||||||
nfs_readdata_free(data);
|
nfs_readdata_free(data);
|
||||||
}
|
}
|
||||||
SetPageError(page);
|
|
||||||
nfs_readpage_release(req);
|
nfs_readpage_release(req);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
@ -357,7 +351,6 @@ static int nfs_pagein_one(struct nfs_pageio_descriptor *desc, struct list_head *
|
|||||||
req = nfs_list_entry(head->next);
|
req = nfs_list_entry(head->next);
|
||||||
nfs_list_remove_request(req);
|
nfs_list_remove_request(req);
|
||||||
nfs_list_add_request(req, &data->pages);
|
nfs_list_add_request(req, &data->pages);
|
||||||
ClearPageError(req->wb_page);
|
|
||||||
*pages++ = req->wb_page;
|
*pages++ = req->wb_page;
|
||||||
}
|
}
|
||||||
req = nfs_list_entry(data->pages.next);
|
req = nfs_list_entry(data->pages.next);
|
||||||
@ -435,7 +428,7 @@ static void nfs_readpage_retry(struct rpc_task *task, struct nfs_read_data *data
|
|||||||
argp->offset += resp->count;
|
argp->offset += resp->count;
|
||||||
argp->pgbase += resp->count;
|
argp->pgbase += resp->count;
|
||||||
argp->count -= resp->count;
|
argp->count -= resp->count;
|
||||||
nfs_restart_rpc(task, NFS_SERVER(data->inode)->nfs_client);
|
rpc_restart_call_prepare(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -462,10 +455,10 @@ static void nfs_readpage_release_partial(void *calldata)
|
|||||||
int status = data->task.tk_status;
|
int status = data->task.tk_status;
|
||||||
|
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
SetPageError(page);
|
set_bit(PG_PARTIAL_READ_FAILED, &req->wb_flags);
|
||||||
|
|
||||||
if (atomic_dec_and_test(&req->wb_complete)) {
|
if (atomic_dec_and_test(&req->wb_complete)) {
|
||||||
if (!PageError(page))
|
if (!test_bit(PG_PARTIAL_READ_FAILED, &req->wb_flags))
|
||||||
SetPageUptodate(page);
|
SetPageUptodate(page);
|
||||||
nfs_readpage_release(req);
|
nfs_readpage_release(req);
|
||||||
}
|
}
|
||||||
@ -541,13 +534,23 @@ static void nfs_readpage_result_full(struct rpc_task *task, void *calldata)
|
|||||||
static void nfs_readpage_release_full(void *calldata)
|
static void nfs_readpage_release_full(void *calldata)
|
||||||
{
|
{
|
||||||
struct nfs_read_data *data = calldata;
|
struct nfs_read_data *data = calldata;
|
||||||
|
struct nfs_pageio_descriptor pgio;
|
||||||
|
|
||||||
|
if (data->pnfs_error) {
|
||||||
|
nfs_pageio_init_read_mds(&pgio, data->inode);
|
||||||
|
pgio.pg_recoalesce = 1;
|
||||||
|
}
|
||||||
while (!list_empty(&data->pages)) {
|
while (!list_empty(&data->pages)) {
|
||||||
struct nfs_page *req = nfs_list_entry(data->pages.next);
|
struct nfs_page *req = nfs_list_entry(data->pages.next);
|
||||||
|
|
||||||
nfs_list_remove_request(req);
|
nfs_list_remove_request(req);
|
||||||
nfs_readpage_release(req);
|
if (!data->pnfs_error)
|
||||||
|
nfs_readpage_release(req);
|
||||||
|
else
|
||||||
|
nfs_pageio_add_request(&pgio, req);
|
||||||
}
|
}
|
||||||
|
if (data->pnfs_error)
|
||||||
|
nfs_pageio_complete(&pgio);
|
||||||
nfs_readdata_release(calldata);
|
nfs_readdata_release(calldata);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -648,7 +651,6 @@ readpage_async_filler(void *data, struct page *page)
|
|||||||
return 0;
|
return 0;
|
||||||
out_error:
|
out_error:
|
||||||
error = PTR_ERR(new);
|
error = PTR_ERR(new);
|
||||||
SetPageError(page);
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
unlock_page(page);
|
unlock_page(page);
|
||||||
return error;
|
return error;
|
||||||
@ -711,16 +713,10 @@ int __init nfs_init_readpagecache(void)
|
|||||||
if (nfs_rdata_cachep == NULL)
|
if (nfs_rdata_cachep == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
nfs_rdata_mempool = mempool_create_slab_pool(MIN_POOL_READ,
|
|
||||||
nfs_rdata_cachep);
|
|
||||||
if (nfs_rdata_mempool == NULL)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nfs_destroy_readpagecache(void)
|
void nfs_destroy_readpagecache(void)
|
||||||
{
|
{
|
||||||
mempool_destroy(nfs_rdata_mempool);
|
|
||||||
kmem_cache_destroy(nfs_rdata_cachep);
|
kmem_cache_destroy(nfs_rdata_cachep);
|
||||||
}
|
}
|
||||||
|
@ -733,18 +733,22 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_NFS_V4
|
||||||
#ifdef CONFIG_NFS_V4_1
|
#ifdef CONFIG_NFS_V4_1
|
||||||
void show_sessions(struct seq_file *m, struct nfs_server *server)
|
static void show_sessions(struct seq_file *m, struct nfs_server *server)
|
||||||
{
|
{
|
||||||
if (nfs4_has_session(server->nfs_client))
|
if (nfs4_has_session(server->nfs_client))
|
||||||
seq_printf(m, ",sessions");
|
seq_printf(m, ",sessions");
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void show_sessions(struct seq_file *m, struct nfs_server *server) {}
|
static void show_sessions(struct seq_file *m, struct nfs_server *server) {}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_NFS_V4
|
||||||
#ifdef CONFIG_NFS_V4_1
|
#ifdef CONFIG_NFS_V4_1
|
||||||
void show_pnfs(struct seq_file *m, struct nfs_server *server)
|
static void show_pnfs(struct seq_file *m, struct nfs_server *server)
|
||||||
{
|
{
|
||||||
seq_printf(m, ",pnfs=");
|
seq_printf(m, ",pnfs=");
|
||||||
if (server->pnfs_curr_ld)
|
if (server->pnfs_curr_ld)
|
||||||
@ -752,9 +756,10 @@ void show_pnfs(struct seq_file *m, struct nfs_server *server)
|
|||||||
else
|
else
|
||||||
seq_printf(m, "not configured");
|
seq_printf(m, "not configured");
|
||||||
}
|
}
|
||||||
#else /* CONFIG_NFS_V4_1 */
|
#else
|
||||||
void show_pnfs(struct seq_file *m, struct nfs_server *server) {}
|
static void show_pnfs(struct seq_file *m, struct nfs_server *server) {}
|
||||||
#endif /* CONFIG_NFS_V4_1 */
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
static int nfs_show_devname(struct seq_file *m, struct vfsmount *mnt)
|
static int nfs_show_devname(struct seq_file *m, struct vfsmount *mnt)
|
||||||
{
|
{
|
||||||
|
@ -87,7 +87,7 @@ static void nfs_async_unlink_done(struct rpc_task *task, void *calldata)
|
|||||||
struct inode *dir = data->dir;
|
struct inode *dir = data->dir;
|
||||||
|
|
||||||
if (!NFS_PROTO(dir)->unlink_done(task, dir))
|
if (!NFS_PROTO(dir)->unlink_done(task, dir))
|
||||||
nfs_restart_rpc(task, NFS_SERVER(dir)->nfs_client);
|
rpc_restart_call_prepare(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -369,7 +369,7 @@ static void nfs_async_rename_done(struct rpc_task *task, void *calldata)
|
|||||||
struct dentry *new_dentry = data->new_dentry;
|
struct dentry *new_dentry = data->new_dentry;
|
||||||
|
|
||||||
if (!NFS_PROTO(old_dir)->rename_done(task, old_dir, new_dir)) {
|
if (!NFS_PROTO(old_dir)->rename_done(task, old_dir, new_dir)) {
|
||||||
nfs_restart_rpc(task, NFS_SERVER(old_dir)->nfs_client);
|
rpc_restart_call_prepare(task);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,7 +390,7 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req)
|
|||||||
error = radix_tree_insert(&nfsi->nfs_page_tree, req->wb_index, req);
|
error = radix_tree_insert(&nfsi->nfs_page_tree, req->wb_index, req);
|
||||||
BUG_ON(error);
|
BUG_ON(error);
|
||||||
if (!nfsi->npages && nfs_have_delegation(inode, FMODE_WRITE))
|
if (!nfsi->npages && nfs_have_delegation(inode, FMODE_WRITE))
|
||||||
nfsi->change_attr++;
|
inode->i_version++;
|
||||||
set_bit(PG_MAPPED, &req->wb_flags);
|
set_bit(PG_MAPPED, &req->wb_flags);
|
||||||
SetPagePrivate(req->wb_page);
|
SetPagePrivate(req->wb_page);
|
||||||
set_page_private(req->wb_page, (unsigned long)req);
|
set_page_private(req->wb_page, (unsigned long)req);
|
||||||
@ -428,7 +428,6 @@ static void
|
|||||||
nfs_mark_request_dirty(struct nfs_page *req)
|
nfs_mark_request_dirty(struct nfs_page *req)
|
||||||
{
|
{
|
||||||
__set_page_dirty_nobuffers(req->wb_page);
|
__set_page_dirty_nobuffers(req->wb_page);
|
||||||
__mark_inode_dirty(req->wb_page->mapping->host, I_DIRTY_DATASYNC);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
|
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
|
||||||
@ -762,6 +761,8 @@ int nfs_updatepage(struct file *file, struct page *page,
|
|||||||
status = nfs_writepage_setup(ctx, page, offset, count);
|
status = nfs_writepage_setup(ctx, page, offset, count);
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
nfs_set_pageerror(page);
|
nfs_set_pageerror(page);
|
||||||
|
else
|
||||||
|
__set_page_dirty_nobuffers(page);
|
||||||
|
|
||||||
dprintk("NFS: nfs_updatepage returns %d (isize %lld)\n",
|
dprintk("NFS: nfs_updatepage returns %d (isize %lld)\n",
|
||||||
status, (long long)i_size_read(inode));
|
status, (long long)i_size_read(inode));
|
||||||
@ -1010,7 +1011,6 @@ static int nfs_flush_one(struct nfs_pageio_descriptor *desc, struct list_head *r
|
|||||||
req = nfs_list_entry(head->next);
|
req = nfs_list_entry(head->next);
|
||||||
nfs_list_remove_request(req);
|
nfs_list_remove_request(req);
|
||||||
nfs_list_add_request(req, &data->pages);
|
nfs_list_add_request(req, &data->pages);
|
||||||
ClearPageError(req->wb_page);
|
|
||||||
*pages++ = req->wb_page;
|
*pages++ = req->wb_page;
|
||||||
}
|
}
|
||||||
req = nfs_list_entry(data->pages.next);
|
req = nfs_list_entry(data->pages.next);
|
||||||
@ -1165,7 +1165,13 @@ static void nfs_writeback_done_full(struct rpc_task *task, void *calldata)
|
|||||||
static void nfs_writeback_release_full(void *calldata)
|
static void nfs_writeback_release_full(void *calldata)
|
||||||
{
|
{
|
||||||
struct nfs_write_data *data = calldata;
|
struct nfs_write_data *data = calldata;
|
||||||
int status = data->task.tk_status;
|
int ret, status = data->task.tk_status;
|
||||||
|
struct nfs_pageio_descriptor pgio;
|
||||||
|
|
||||||
|
if (data->pnfs_error) {
|
||||||
|
nfs_pageio_init_write_mds(&pgio, data->inode, FLUSH_STABLE);
|
||||||
|
pgio.pg_recoalesce = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Update attributes as result of writeback. */
|
/* Update attributes as result of writeback. */
|
||||||
while (!list_empty(&data->pages)) {
|
while (!list_empty(&data->pages)) {
|
||||||
@ -1181,6 +1187,11 @@ static void nfs_writeback_release_full(void *calldata)
|
|||||||
req->wb_bytes,
|
req->wb_bytes,
|
||||||
(long long)req_offset(req));
|
(long long)req_offset(req));
|
||||||
|
|
||||||
|
if (data->pnfs_error) {
|
||||||
|
dprintk(", pnfs error = %d\n", data->pnfs_error);
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
|
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
nfs_set_pageerror(page);
|
nfs_set_pageerror(page);
|
||||||
nfs_context_set_write_error(req->wb_context, status);
|
nfs_context_set_write_error(req->wb_context, status);
|
||||||
@ -1200,7 +1211,19 @@ remove_request:
|
|||||||
next:
|
next:
|
||||||
nfs_clear_page_tag_locked(req);
|
nfs_clear_page_tag_locked(req);
|
||||||
nfs_end_page_writeback(page);
|
nfs_end_page_writeback(page);
|
||||||
|
if (data->pnfs_error) {
|
||||||
|
lock_page(page);
|
||||||
|
nfs_pageio_cond_complete(&pgio, page->index);
|
||||||
|
ret = nfs_page_async_flush(&pgio, page, 0);
|
||||||
|
if (ret) {
|
||||||
|
nfs_set_pageerror(page);
|
||||||
|
dprintk("rewrite to MDS error = %d\n", ret);
|
||||||
|
}
|
||||||
|
unlock_page(page);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (data->pnfs_error)
|
||||||
|
nfs_pageio_complete(&pgio);
|
||||||
nfs_writedata_release(calldata);
|
nfs_writedata_release(calldata);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1281,7 +1304,7 @@ void nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
|
|||||||
*/
|
*/
|
||||||
argp->stable = NFS_FILE_SYNC;
|
argp->stable = NFS_FILE_SYNC;
|
||||||
}
|
}
|
||||||
nfs_restart_rpc(task, server->nfs_client);
|
rpc_restart_call_prepare(task);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (time_before(complain, jiffies)) {
|
if (time_before(complain, jiffies)) {
|
||||||
@ -1553,6 +1576,10 @@ static int nfs_commit_unstable_pages(struct inode *inode, struct writeback_contr
|
|||||||
int flags = FLUSH_SYNC;
|
int flags = FLUSH_SYNC;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
/* no commits means nothing needs to be done */
|
||||||
|
if (!nfsi->ncommit)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if (wbc->sync_mode == WB_SYNC_NONE) {
|
if (wbc->sync_mode == WB_SYNC_NONE) {
|
||||||
/* Don't commit yet if this is a non-blocking flush and there
|
/* Don't commit yet if this is a non-blocking flush and there
|
||||||
* are a lot of outstanding writes for this mapping.
|
* are a lot of outstanding writes for this mapping.
|
||||||
@ -1686,34 +1713,20 @@ out_error:
|
|||||||
int nfs_migrate_page(struct address_space *mapping, struct page *newpage,
|
int nfs_migrate_page(struct address_space *mapping, struct page *newpage,
|
||||||
struct page *page)
|
struct page *page)
|
||||||
{
|
{
|
||||||
struct nfs_page *req;
|
/*
|
||||||
int ret;
|
* If PagePrivate is set, then the page is currently associated with
|
||||||
|
* an in-progress read or write request. Don't try to migrate it.
|
||||||
|
*
|
||||||
|
* FIXME: we could do this in principle, but we'll need a way to ensure
|
||||||
|
* that we can safely release the inode reference while holding
|
||||||
|
* the page lock.
|
||||||
|
*/
|
||||||
|
if (PagePrivate(page))
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
nfs_fscache_release_page(page, GFP_KERNEL);
|
nfs_fscache_release_page(page, GFP_KERNEL);
|
||||||
|
|
||||||
req = nfs_find_and_lock_request(page, false);
|
return migrate_page(mapping, newpage, page);
|
||||||
ret = PTR_ERR(req);
|
|
||||||
if (IS_ERR(req))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
ret = migrate_page(mapping, newpage, page);
|
|
||||||
if (!req)
|
|
||||||
goto out;
|
|
||||||
if (ret)
|
|
||||||
goto out_unlock;
|
|
||||||
page_cache_get(newpage);
|
|
||||||
spin_lock(&mapping->host->i_lock);
|
|
||||||
req->wb_page = newpage;
|
|
||||||
SetPagePrivate(newpage);
|
|
||||||
set_page_private(newpage, (unsigned long)req);
|
|
||||||
ClearPagePrivate(page);
|
|
||||||
set_page_private(page, 0);
|
|
||||||
spin_unlock(&mapping->host->i_lock);
|
|
||||||
page_cache_release(page);
|
|
||||||
out_unlock:
|
|
||||||
nfs_clear_page_tag_locked(req);
|
|
||||||
out:
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -149,7 +149,6 @@ struct nfs_inode {
|
|||||||
unsigned long read_cache_jiffies;
|
unsigned long read_cache_jiffies;
|
||||||
unsigned long attrtimeo;
|
unsigned long attrtimeo;
|
||||||
unsigned long attrtimeo_timestamp;
|
unsigned long attrtimeo_timestamp;
|
||||||
__u64 change_attr; /* v4 only */
|
|
||||||
|
|
||||||
unsigned long attr_gencount;
|
unsigned long attr_gencount;
|
||||||
/* "Generation counter" for the attribute cache. This is
|
/* "Generation counter" for the attribute cache. This is
|
||||||
|
@ -34,6 +34,7 @@ enum {
|
|||||||
PG_NEED_COMMIT,
|
PG_NEED_COMMIT,
|
||||||
PG_NEED_RESCHED,
|
PG_NEED_RESCHED,
|
||||||
PG_PNFS_COMMIT,
|
PG_PNFS_COMMIT,
|
||||||
|
PG_PARTIAL_READ_FAILED,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nfs_inode;
|
struct nfs_inode;
|
||||||
|
@ -1133,7 +1133,6 @@ struct nfs_page;
|
|||||||
#define NFS_PAGEVEC_SIZE (8U)
|
#define NFS_PAGEVEC_SIZE (8U)
|
||||||
|
|
||||||
struct nfs_read_data {
|
struct nfs_read_data {
|
||||||
int flags;
|
|
||||||
struct rpc_task task;
|
struct rpc_task task;
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
struct rpc_cred *cred;
|
struct rpc_cred *cred;
|
||||||
@ -1156,7 +1155,6 @@ struct nfs_read_data {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct nfs_write_data {
|
struct nfs_write_data {
|
||||||
int flags;
|
|
||||||
struct rpc_task task;
|
struct rpc_task task;
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
struct rpc_cred *cred;
|
struct rpc_cred *cred;
|
||||||
@ -1197,9 +1195,6 @@ struct nfs_rpc_ops {
|
|||||||
|
|
||||||
int (*getroot) (struct nfs_server *, struct nfs_fh *,
|
int (*getroot) (struct nfs_server *, struct nfs_fh *,
|
||||||
struct nfs_fsinfo *);
|
struct nfs_fsinfo *);
|
||||||
int (*lookupfh)(struct nfs_server *, struct nfs_fh *,
|
|
||||||
struct qstr *, struct nfs_fh *,
|
|
||||||
struct nfs_fattr *);
|
|
||||||
int (*getattr) (struct nfs_server *, struct nfs_fh *,
|
int (*getattr) (struct nfs_server *, struct nfs_fh *,
|
||||||
struct nfs_fattr *);
|
struct nfs_fattr *);
|
||||||
int (*setattr) (struct dentry *, struct nfs_fattr *,
|
int (*setattr) (struct dentry *, struct nfs_fattr *,
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#ifndef _LINUX_SUNRPC_CLNT_H
|
#ifndef _LINUX_SUNRPC_CLNT_H
|
||||||
#define _LINUX_SUNRPC_CLNT_H
|
#define _LINUX_SUNRPC_CLNT_H
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
#include <linux/socket.h>
|
#include <linux/socket.h>
|
||||||
#include <linux/in.h>
|
#include <linux/in.h>
|
||||||
#include <linux/in6.h>
|
#include <linux/in6.h>
|
||||||
@ -161,7 +162,7 @@ const char *rpc_peeraddr2str(struct rpc_clnt *, enum rpc_display_format_t);
|
|||||||
size_t rpc_ntop(const struct sockaddr *, char *, const size_t);
|
size_t rpc_ntop(const struct sockaddr *, char *, const size_t);
|
||||||
size_t rpc_pton(const char *, const size_t,
|
size_t rpc_pton(const char *, const size_t,
|
||||||
struct sockaddr *, const size_t);
|
struct sockaddr *, const size_t);
|
||||||
char * rpc_sockaddr2uaddr(const struct sockaddr *);
|
char * rpc_sockaddr2uaddr(const struct sockaddr *, gfp_t);
|
||||||
size_t rpc_uaddr2sockaddr(const char *, const size_t,
|
size_t rpc_uaddr2sockaddr(const char *, const size_t,
|
||||||
struct sockaddr *, const size_t);
|
struct sockaddr *, const size_t);
|
||||||
|
|
||||||
|
@ -44,6 +44,8 @@ RPC_I(struct inode *inode)
|
|||||||
return container_of(inode, struct rpc_inode, vfs_inode);
|
return container_of(inode, struct rpc_inode, vfs_inode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern ssize_t rpc_pipe_generic_upcall(struct file *, struct rpc_pipe_msg *,
|
||||||
|
char __user *, size_t);
|
||||||
extern int rpc_queue_upcall(struct inode *, struct rpc_pipe_msg *);
|
extern int rpc_queue_upcall(struct inode *, struct rpc_pipe_msg *);
|
||||||
|
|
||||||
struct rpc_clnt;
|
struct rpc_clnt;
|
||||||
|
@ -255,12 +255,13 @@ EXPORT_SYMBOL_GPL(rpc_pton);
|
|||||||
/**
|
/**
|
||||||
* rpc_sockaddr2uaddr - Construct a universal address string from @sap.
|
* rpc_sockaddr2uaddr - Construct a universal address string from @sap.
|
||||||
* @sap: socket address
|
* @sap: socket address
|
||||||
|
* @gfp_flags: allocation mode
|
||||||
*
|
*
|
||||||
* Returns a %NUL-terminated string in dynamically allocated memory;
|
* Returns a %NUL-terminated string in dynamically allocated memory;
|
||||||
* otherwise NULL is returned if an error occurred. Caller must
|
* otherwise NULL is returned if an error occurred. Caller must
|
||||||
* free the returned string.
|
* free the returned string.
|
||||||
*/
|
*/
|
||||||
char *rpc_sockaddr2uaddr(const struct sockaddr *sap)
|
char *rpc_sockaddr2uaddr(const struct sockaddr *sap, gfp_t gfp_flags)
|
||||||
{
|
{
|
||||||
char portbuf[RPCBIND_MAXUADDRPLEN];
|
char portbuf[RPCBIND_MAXUADDRPLEN];
|
||||||
char addrbuf[RPCBIND_MAXUADDRLEN];
|
char addrbuf[RPCBIND_MAXUADDRLEN];
|
||||||
@ -288,9 +289,8 @@ char *rpc_sockaddr2uaddr(const struct sockaddr *sap)
|
|||||||
if (strlcat(addrbuf, portbuf, sizeof(addrbuf)) > sizeof(addrbuf))
|
if (strlcat(addrbuf, portbuf, sizeof(addrbuf)) > sizeof(addrbuf))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return kstrdup(addrbuf, GFP_KERNEL);
|
return kstrdup(addrbuf, gfp_flags);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rpc_sockaddr2uaddr);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rpc_uaddr2sockaddr - convert a universal address to a socket address.
|
* rpc_uaddr2sockaddr - convert a universal address to a socket address.
|
||||||
|
@ -603,26 +603,6 @@ out:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
|
||||||
gss_pipe_upcall(struct file *filp, struct rpc_pipe_msg *msg,
|
|
||||||
char __user *dst, size_t buflen)
|
|
||||||
{
|
|
||||||
char *data = (char *)msg->data + msg->copied;
|
|
||||||
size_t mlen = min(msg->len, buflen);
|
|
||||||
unsigned long left;
|
|
||||||
|
|
||||||
left = copy_to_user(dst, data, mlen);
|
|
||||||
if (left == mlen) {
|
|
||||||
msg->errno = -EFAULT;
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
mlen -= left;
|
|
||||||
msg->copied += mlen;
|
|
||||||
msg->errno = 0;
|
|
||||||
return mlen;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MSG_BUF_MAXSIZE 1024
|
#define MSG_BUF_MAXSIZE 1024
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
@ -1590,7 +1570,7 @@ static const struct rpc_credops gss_nullops = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct rpc_pipe_ops gss_upcall_ops_v0 = {
|
static const struct rpc_pipe_ops gss_upcall_ops_v0 = {
|
||||||
.upcall = gss_pipe_upcall,
|
.upcall = rpc_pipe_generic_upcall,
|
||||||
.downcall = gss_pipe_downcall,
|
.downcall = gss_pipe_downcall,
|
||||||
.destroy_msg = gss_pipe_destroy_msg,
|
.destroy_msg = gss_pipe_destroy_msg,
|
||||||
.open_pipe = gss_pipe_open_v0,
|
.open_pipe = gss_pipe_open_v0,
|
||||||
@ -1598,7 +1578,7 @@ static const struct rpc_pipe_ops gss_upcall_ops_v0 = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct rpc_pipe_ops gss_upcall_ops_v1 = {
|
static const struct rpc_pipe_ops gss_upcall_ops_v1 = {
|
||||||
.upcall = gss_pipe_upcall,
|
.upcall = rpc_pipe_generic_upcall,
|
||||||
.downcall = gss_pipe_downcall,
|
.downcall = gss_pipe_downcall,
|
||||||
.destroy_msg = gss_pipe_destroy_msg,
|
.destroy_msg = gss_pipe_destroy_msg,
|
||||||
.open_pipe = gss_pipe_open_v1,
|
.open_pipe = gss_pipe_open_v1,
|
||||||
|
@ -850,7 +850,9 @@ rpc_restart_call_prepare(struct rpc_task *task)
|
|||||||
{
|
{
|
||||||
if (RPC_ASSASSINATED(task))
|
if (RPC_ASSASSINATED(task))
|
||||||
return 0;
|
return 0;
|
||||||
task->tk_action = rpc_prepare_task;
|
task->tk_action = call_start;
|
||||||
|
if (task->tk_ops->rpc_call_prepare != NULL)
|
||||||
|
task->tk_action = rpc_prepare_task;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rpc_restart_call_prepare);
|
EXPORT_SYMBOL_GPL(rpc_restart_call_prepare);
|
||||||
|
@ -77,6 +77,26 @@ rpc_timeout_upcall_queue(struct work_struct *work)
|
|||||||
rpc_purge_list(rpci, &free_list, destroy_msg, -ETIMEDOUT);
|
rpc_purge_list(rpci, &free_list, destroy_msg, -ETIMEDOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t rpc_pipe_generic_upcall(struct file *filp, struct rpc_pipe_msg *msg,
|
||||||
|
char __user *dst, size_t buflen)
|
||||||
|
{
|
||||||
|
char *data = (char *)msg->data + msg->copied;
|
||||||
|
size_t mlen = min(msg->len - msg->copied, buflen);
|
||||||
|
unsigned long left;
|
||||||
|
|
||||||
|
left = copy_to_user(dst, data, mlen);
|
||||||
|
if (left == mlen) {
|
||||||
|
msg->errno = -EFAULT;
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
mlen -= left;
|
||||||
|
msg->copied += mlen;
|
||||||
|
msg->errno = 0;
|
||||||
|
return mlen;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(rpc_pipe_generic_upcall);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rpc_queue_upcall - queue an upcall message to userspace
|
* rpc_queue_upcall - queue an upcall message to userspace
|
||||||
* @inode: inode of upcall pipe on which to queue given message
|
* @inode: inode of upcall pipe on which to queue given message
|
||||||
|
@ -410,7 +410,7 @@ static int rpcb_register_inet4(const struct sockaddr *sap,
|
|||||||
unsigned short port = ntohs(sin->sin_port);
|
unsigned short port = ntohs(sin->sin_port);
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
map->r_addr = rpc_sockaddr2uaddr(sap);
|
map->r_addr = rpc_sockaddr2uaddr(sap, GFP_KERNEL);
|
||||||
|
|
||||||
dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with "
|
dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with "
|
||||||
"local rpcbind\n", (port ? "" : "un"),
|
"local rpcbind\n", (port ? "" : "un"),
|
||||||
@ -437,7 +437,7 @@ static int rpcb_register_inet6(const struct sockaddr *sap,
|
|||||||
unsigned short port = ntohs(sin6->sin6_port);
|
unsigned short port = ntohs(sin6->sin6_port);
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
map->r_addr = rpc_sockaddr2uaddr(sap);
|
map->r_addr = rpc_sockaddr2uaddr(sap, GFP_KERNEL);
|
||||||
|
|
||||||
dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with "
|
dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with "
|
||||||
"local rpcbind\n", (port ? "" : "un"),
|
"local rpcbind\n", (port ? "" : "un"),
|
||||||
@ -686,7 +686,7 @@ void rpcb_getport_async(struct rpc_task *task)
|
|||||||
case RPCBVERS_4:
|
case RPCBVERS_4:
|
||||||
case RPCBVERS_3:
|
case RPCBVERS_3:
|
||||||
map->r_netid = rpc_peeraddr2str(clnt, RPC_DISPLAY_NETID);
|
map->r_netid = rpc_peeraddr2str(clnt, RPC_DISPLAY_NETID);
|
||||||
map->r_addr = rpc_sockaddr2uaddr(sap);
|
map->r_addr = rpc_sockaddr2uaddr(sap, GFP_ATOMIC);
|
||||||
map->r_owner = "";
|
map->r_owner = "";
|
||||||
break;
|
break;
|
||||||
case RPCBVERS_2:
|
case RPCBVERS_2:
|
||||||
|
Loading…
Reference in New Issue
Block a user