aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c177
1 files changed, 93 insertions, 84 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index dcda0ba7af60..f0c849c98fe4 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -52,6 +52,7 @@
52#include <linux/namei.h> 52#include <linux/namei.h>
53#include <linux/mount.h> 53#include <linux/mount.h>
54#include <linux/module.h> 54#include <linux/module.h>
55#include <linux/nfs_idmap.h>
55#include <linux/sunrpc/bc_xprt.h> 56#include <linux/sunrpc/bc_xprt.h>
56#include <linux/xattr.h> 57#include <linux/xattr.h>
57#include <linux/utsname.h> 58#include <linux/utsname.h>
@@ -364,9 +365,8 @@ static void renew_lease(const struct nfs_server *server, unsigned long timestamp
364 * Must be called while holding tbl->slot_tbl_lock 365 * Must be called while holding tbl->slot_tbl_lock
365 */ 366 */
366static void 367static void
367nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *free_slot) 368nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid)
368{ 369{
369 int free_slotid = free_slot - tbl->slots;
370 int slotid = free_slotid; 370 int slotid = free_slotid;
371 371
372 BUG_ON(slotid < 0 || slotid >= NFS4_MAX_SLOT_TABLE); 372 BUG_ON(slotid < 0 || slotid >= NFS4_MAX_SLOT_TABLE);
@@ -431,7 +431,7 @@ static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res)
431 } 431 }
432 432
433 spin_lock(&tbl->slot_tbl_lock); 433 spin_lock(&tbl->slot_tbl_lock);
434 nfs4_free_slot(tbl, res->sr_slot); 434 nfs4_free_slot(tbl, res->sr_slot - tbl->slots);
435 nfs4_check_drain_fc_complete(res->sr_session); 435 nfs4_check_drain_fc_complete(res->sr_session);
436 spin_unlock(&tbl->slot_tbl_lock); 436 spin_unlock(&tbl->slot_tbl_lock);
437 res->sr_slot = NULL; 437 res->sr_slot = NULL;
@@ -554,13 +554,10 @@ int nfs41_setup_sequence(struct nfs4_session *session,
554 spin_lock(&tbl->slot_tbl_lock); 554 spin_lock(&tbl->slot_tbl_lock);
555 if (test_bit(NFS4_SESSION_DRAINING, &session->session_state) && 555 if (test_bit(NFS4_SESSION_DRAINING, &session->session_state) &&
556 !rpc_task_has_priority(task, RPC_PRIORITY_PRIVILEGED)) { 556 !rpc_task_has_priority(task, RPC_PRIORITY_PRIVILEGED)) {
557 /* 557 /* The state manager will wait until the slot table is empty */
558 * The state manager will wait until the slot table is empty.
559 * Schedule the reset thread
560 */
561 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL); 558 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
562 spin_unlock(&tbl->slot_tbl_lock); 559 spin_unlock(&tbl->slot_tbl_lock);
563 dprintk("%s Schedule Session Reset\n", __func__); 560 dprintk("%s session is draining\n", __func__);
564 return -EAGAIN; 561 return -EAGAIN;
565 } 562 }
566 563
@@ -765,6 +762,8 @@ struct nfs4_opendata {
765 struct nfs_openres o_res; 762 struct nfs_openres o_res;
766 struct nfs_open_confirmargs c_arg; 763 struct nfs_open_confirmargs c_arg;
767 struct nfs_open_confirmres c_res; 764 struct nfs_open_confirmres c_res;
765 struct nfs4_string owner_name;
766 struct nfs4_string group_name;
768 struct nfs_fattr f_attr; 767 struct nfs_fattr f_attr;
769 struct nfs_fattr dir_attr; 768 struct nfs_fattr dir_attr;
770 struct dentry *dir; 769 struct dentry *dir;
@@ -788,6 +787,7 @@ static void nfs4_init_opendata_res(struct nfs4_opendata *p)
788 p->o_res.server = p->o_arg.server; 787 p->o_res.server = p->o_arg.server;
789 nfs_fattr_init(&p->f_attr); 788 nfs_fattr_init(&p->f_attr);
790 nfs_fattr_init(&p->dir_attr); 789 nfs_fattr_init(&p->dir_attr);
790 nfs_fattr_init_names(&p->f_attr, &p->owner_name, &p->group_name);
791} 791}
792 792
793static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, 793static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
@@ -819,6 +819,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
819 p->o_arg.name = &dentry->d_name; 819 p->o_arg.name = &dentry->d_name;
820 p->o_arg.server = server; 820 p->o_arg.server = server;
821 p->o_arg.bitmask = server->attr_bitmask; 821 p->o_arg.bitmask = server->attr_bitmask;
822 p->o_arg.dir_bitmask = server->cache_consistency_bitmask;
822 p->o_arg.claim = NFS4_OPEN_CLAIM_NULL; 823 p->o_arg.claim = NFS4_OPEN_CLAIM_NULL;
823 if (flags & O_CREAT) { 824 if (flags & O_CREAT) {
824 u32 *s; 825 u32 *s;
@@ -855,6 +856,7 @@ static void nfs4_opendata_free(struct kref *kref)
855 dput(p->dir); 856 dput(p->dir);
856 dput(p->dentry); 857 dput(p->dentry);
857 nfs_sb_deactive(sb); 858 nfs_sb_deactive(sb);
859 nfs_fattr_free_names(&p->f_attr);
858 kfree(p); 860 kfree(p);
859} 861}
860 862
@@ -1579,6 +1581,8 @@ static int _nfs4_recover_proc_open(struct nfs4_opendata *data)
1579 if (status != 0 || !data->rpc_done) 1581 if (status != 0 || !data->rpc_done)
1580 return status; 1582 return status;
1581 1583
1584 nfs_fattr_map_and_free_names(NFS_SERVER(dir), &data->f_attr);
1585
1582 nfs_refresh_inode(dir, o_res->dir_attr); 1586 nfs_refresh_inode(dir, o_res->dir_attr);
1583 1587
1584 if (o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) { 1588 if (o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) {
@@ -1611,6 +1615,8 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
1611 return status; 1615 return status;
1612 } 1616 }
1613 1617
1618 nfs_fattr_map_and_free_names(server, &data->f_attr);
1619
1614 if (o_arg->open_flags & O_CREAT) { 1620 if (o_arg->open_flags & O_CREAT) {
1615 update_changeattr(dir, &o_res->cinfo); 1621 update_changeattr(dir, &o_res->cinfo);
1616 nfs_post_op_update_inode(dir, o_res->dir_attr); 1622 nfs_post_op_update_inode(dir, o_res->dir_attr);
@@ -3431,19 +3437,6 @@ static inline int nfs4_server_supports_acls(struct nfs_server *server)
3431 */ 3437 */
3432#define NFS4ACL_MAXPAGES (XATTR_SIZE_MAX >> PAGE_CACHE_SHIFT) 3438#define NFS4ACL_MAXPAGES (XATTR_SIZE_MAX >> PAGE_CACHE_SHIFT)
3433 3439
3434static void buf_to_pages(const void *buf, size_t buflen,
3435 struct page **pages, unsigned int *pgbase)
3436{
3437 const void *p = buf;
3438
3439 *pgbase = offset_in_page(buf);
3440 p -= *pgbase;
3441 while (p < buf + buflen) {
3442 *(pages++) = virt_to_page(p);
3443 p += PAGE_CACHE_SIZE;
3444 }
3445}
3446
3447static int buf_to_pages_noslab(const void *buf, size_t buflen, 3440static int buf_to_pages_noslab(const void *buf, size_t buflen,
3448 struct page **pages, unsigned int *pgbase) 3441 struct page **pages, unsigned int *pgbase)
3449{ 3442{
@@ -3540,9 +3533,19 @@ out:
3540 nfs4_set_cached_acl(inode, acl); 3533 nfs4_set_cached_acl(inode, acl);
3541} 3534}
3542 3535
3536/*
3537 * The getxattr API returns the required buffer length when called with a
3538 * NULL buf. The NFSv4 acl tool then calls getxattr again after allocating
3539 * the required buf. On a NULL buf, we send a page of data to the server
3540 * guessing that the ACL request can be serviced by a page. If so, we cache
3541 * up to the page of ACL data, and the 2nd call to getxattr is serviced by
3542 * the cache. If not so, we throw away the page, and cache the required
3543 * length. The next getxattr call will then produce another round trip to
3544 * the server, this time with the input buf of the required size.
3545 */
3543static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen) 3546static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
3544{ 3547{
3545 struct page *pages[NFS4ACL_MAXPAGES]; 3548 struct page *pages[NFS4ACL_MAXPAGES] = {NULL, };
3546 struct nfs_getaclargs args = { 3549 struct nfs_getaclargs args = {
3547 .fh = NFS_FH(inode), 3550 .fh = NFS_FH(inode),
3548 .acl_pages = pages, 3551 .acl_pages = pages,
@@ -3557,41 +3560,60 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
3557 .rpc_argp = &args, 3560 .rpc_argp = &args,
3558 .rpc_resp = &res, 3561 .rpc_resp = &res,
3559 }; 3562 };
3560 struct page *localpage = NULL; 3563 int ret = -ENOMEM, npages, i, acl_len = 0;
3561 int ret;
3562 3564
3563 if (buflen < PAGE_SIZE) { 3565 npages = (buflen + PAGE_SIZE - 1) >> PAGE_SHIFT;
3564 /* As long as we're doing a round trip to the server anyway, 3566 /* As long as we're doing a round trip to the server anyway,
3565 * let's be prepared for a page of acl data. */ 3567 * let's be prepared for a page of acl data. */
3566 localpage = alloc_page(GFP_KERNEL); 3568 if (npages == 0)
3567 resp_buf = page_address(localpage); 3569 npages = 1;
3568 if (localpage == NULL) 3570
3569 return -ENOMEM; 3571 for (i = 0; i < npages; i++) {
3570 args.acl_pages[0] = localpage; 3572 pages[i] = alloc_page(GFP_KERNEL);
3571 args.acl_pgbase = 0; 3573 if (!pages[i])
3572 args.acl_len = PAGE_SIZE; 3574 goto out_free;
3573 } else {
3574 resp_buf = buf;
3575 buf_to_pages(buf, buflen, args.acl_pages, &args.acl_pgbase);
3576 } 3575 }
3577 ret = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode), &msg, &args.seq_args, &res.seq_res, 0); 3576 if (npages > 1) {
3577 /* for decoding across pages */
3578 args.acl_scratch = alloc_page(GFP_KERNEL);
3579 if (!args.acl_scratch)
3580 goto out_free;
3581 }
3582 args.acl_len = npages * PAGE_SIZE;
3583 args.acl_pgbase = 0;
3584 /* Let decode_getfacl know not to fail if the ACL data is larger than
3585 * the page we send as a guess */
3586 if (buf == NULL)
3587 res.acl_flags |= NFS4_ACL_LEN_REQUEST;
3588 resp_buf = page_address(pages[0]);
3589
3590 dprintk("%s buf %p buflen %zu npages %d args.acl_len %zu\n",
3591 __func__, buf, buflen, npages, args.acl_len);
3592 ret = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode),
3593 &msg, &args.seq_args, &res.seq_res, 0);
3578 if (ret) 3594 if (ret)
3579 goto out_free; 3595 goto out_free;
3580 if (res.acl_len > args.acl_len) 3596
3581 nfs4_write_cached_acl(inode, NULL, res.acl_len); 3597 acl_len = res.acl_len - res.acl_data_offset;
3598 if (acl_len > args.acl_len)
3599 nfs4_write_cached_acl(inode, NULL, acl_len);
3582 else 3600 else
3583 nfs4_write_cached_acl(inode, resp_buf, res.acl_len); 3601 nfs4_write_cached_acl(inode, resp_buf + res.acl_data_offset,
3602 acl_len);
3584 if (buf) { 3603 if (buf) {
3585 ret = -ERANGE; 3604 ret = -ERANGE;
3586 if (res.acl_len > buflen) 3605 if (acl_len > buflen)
3587 goto out_free; 3606 goto out_free;
3588 if (localpage) 3607 _copy_from_pages(buf, pages, res.acl_data_offset,
3589 memcpy(buf, resp_buf, res.acl_len); 3608 res.acl_len);
3590 } 3609 }
3591 ret = res.acl_len; 3610 ret = acl_len;
3592out_free: 3611out_free:
3593 if (localpage) 3612 for (i = 0; i < npages; i++)
3594 __free_page(localpage); 3613 if (pages[i])
3614 __free_page(pages[i]);
3615 if (args.acl_scratch)
3616 __free_page(args.acl_scratch);
3595 return ret; 3617 return ret;
3596} 3618}
3597 3619
@@ -3622,6 +3644,8 @@ static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen)
3622 nfs_zap_acl_cache(inode); 3644 nfs_zap_acl_cache(inode);
3623 ret = nfs4_read_cached_acl(inode, buf, buflen); 3645 ret = nfs4_read_cached_acl(inode, buf, buflen);
3624 if (ret != -ENOENT) 3646 if (ret != -ENOENT)
3647 /* -ENOENT is returned if there is no ACL or if there is an ACL
3648 * but no cached acl data, just the acl length */
3625 return ret; 3649 return ret;
3626 return nfs4_get_acl_uncached(inode, buf, buflen); 3650 return nfs4_get_acl_uncached(inode, buf, buflen);
3627} 3651}
@@ -5022,23 +5046,6 @@ out:
5022 return ret; 5046 return ret;
5023} 5047}
5024 5048
5025/*
5026 * Reset the forechannel and backchannel slot tables
5027 */
5028static int nfs4_reset_slot_tables(struct nfs4_session *session)
5029{
5030 int status;
5031
5032 status = nfs4_reset_slot_table(&session->fc_slot_table,
5033 session->fc_attrs.max_reqs, 1);
5034 if (status)
5035 return status;
5036
5037 status = nfs4_reset_slot_table(&session->bc_slot_table,
5038 session->bc_attrs.max_reqs, 0);
5039 return status;
5040}
5041
5042/* Destroy the slot table */ 5049/* Destroy the slot table */
5043static void nfs4_destroy_slot_tables(struct nfs4_session *session) 5050static void nfs4_destroy_slot_tables(struct nfs4_session *session)
5044{ 5051{
@@ -5084,29 +5091,35 @@ out:
5084} 5091}
5085 5092
5086/* 5093/*
5087 * Initialize the forechannel and backchannel tables 5094 * Initialize or reset the forechannel and backchannel tables
5088 */ 5095 */
5089static int nfs4_init_slot_tables(struct nfs4_session *session) 5096static int nfs4_setup_session_slot_tables(struct nfs4_session *ses)
5090{ 5097{
5091 struct nfs4_slot_table *tbl; 5098 struct nfs4_slot_table *tbl;
5092 int status = 0; 5099 int status;
5093 5100
5094 tbl = &session->fc_slot_table; 5101 dprintk("--> %s\n", __func__);
5102 /* Fore channel */
5103 tbl = &ses->fc_slot_table;
5095 if (tbl->slots == NULL) { 5104 if (tbl->slots == NULL) {
5096 status = nfs4_init_slot_table(tbl, 5105 status = nfs4_init_slot_table(tbl, ses->fc_attrs.max_reqs, 1);
5097 session->fc_attrs.max_reqs, 1); 5106 if (status) /* -ENOMEM */
5107 return status;
5108 } else {
5109 status = nfs4_reset_slot_table(tbl, ses->fc_attrs.max_reqs, 1);
5098 if (status) 5110 if (status)
5099 return status; 5111 return status;
5100 } 5112 }
5101 5113 /* Back channel */
5102 tbl = &session->bc_slot_table; 5114 tbl = &ses->bc_slot_table;
5103 if (tbl->slots == NULL) { 5115 if (tbl->slots == NULL) {
5104 status = nfs4_init_slot_table(tbl, 5116 status = nfs4_init_slot_table(tbl, ses->bc_attrs.max_reqs, 0);
5105 session->bc_attrs.max_reqs, 0);
5106 if (status) 5117 if (status)
5107 nfs4_destroy_slot_tables(session); 5118 /* Fore and back channel share a connection so get
5108 } 5119 * both slot tables or neither */
5109 5120 nfs4_destroy_slot_tables(ses);
5121 } else
5122 status = nfs4_reset_slot_table(tbl, ses->bc_attrs.max_reqs, 0);
5110 return status; 5123 return status;
5111} 5124}
5112 5125
@@ -5294,13 +5307,9 @@ int nfs4_proc_create_session(struct nfs_client *clp)
5294 if (status) 5307 if (status)
5295 goto out; 5308 goto out;
5296 5309
5297 /* Init and reset the fore channel */ 5310 /* Init or reset the session slot tables */
5298 status = nfs4_init_slot_tables(session); 5311 status = nfs4_setup_session_slot_tables(session);
5299 dprintk("slot table initialization returned %d\n", status); 5312 dprintk("slot table setup returned %d\n", status);
5300 if (status)
5301 goto out;
5302 status = nfs4_reset_slot_tables(session);
5303 dprintk("slot table reset returned %d\n", status);
5304 if (status) 5313 if (status)
5305 goto out; 5314 goto out;
5306 5315