aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorDavid Quigley <dpquigl@davequigley.com>2013-05-22 12:50:43 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2013-06-08 16:20:15 -0400
commit14c43f767818c42f91ec7ffa586ee975845f68c8 (patch)
treee1f95f8344f144179d91c9531d83cd7de6684346 /fs/nfs
parent1775fd3e805b6a852ef376256967de69284d7962 (diff)
NFS: Add label lifecycle management
This patch adds the lifecycle management for the security label structure introduced in an earlier patch. The label is not used yet but allocations and freeing of the structure is handled. Signed-off-by: Matthew N. Dodd <Matthew.Dodd@sparta.com> Signed-off-by: Miguel Rodel Felipe <Rodel_FM@dsi.a-star.edu.sg> Signed-off-by: Phua Eu Gene <PHUA_Eu_Gene@dsi.a-star.edu.sg> Signed-off-by: Khin Mi Mi Aung <Mi_Mi_AUNG@dsi.a-star.edu.sg> Signed-off-by: Steve Dickson <steved@redhat.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/dir.c23
-rw-r--r--fs/nfs/inode.c15
-rw-r--r--fs/nfs/nfs4proc.c69
3 files changed, 96 insertions, 11 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index e9ab2cd9dd3d..736b607ac8a8 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -585,10 +585,16 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
585 if (entry.fh == NULL || entry.fattr == NULL) 585 if (entry.fh == NULL || entry.fattr == NULL)
586 goto out; 586 goto out;
587 587
588 entry.label = nfs4_label_alloc(NFS_SERVER(inode), GFP_NOWAIT);
589 if (IS_ERR(entry.label)) {
590 status = PTR_ERR(entry.label);
591 goto out;
592 }
593
588 array = nfs_readdir_get_array(page); 594 array = nfs_readdir_get_array(page);
589 if (IS_ERR(array)) { 595 if (IS_ERR(array)) {
590 status = PTR_ERR(array); 596 status = PTR_ERR(array);
591 goto out; 597 goto out_label_free;
592 } 598 }
593 memset(array, 0, sizeof(struct nfs_cache_array)); 599 memset(array, 0, sizeof(struct nfs_cache_array));
594 array->eof_index = -1; 600 array->eof_index = -1;
@@ -614,6 +620,8 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
614 nfs_readdir_free_large_page(pages_ptr, pages, array_size); 620 nfs_readdir_free_large_page(pages_ptr, pages, array_size);
615out_release_array: 621out_release_array:
616 nfs_readdir_release_array(page); 622 nfs_readdir_release_array(page);
623out_label_free:
624 nfs4_label_free(entry.label);
617out: 625out:
618 nfs_free_fattr(entry.fattr); 626 nfs_free_fattr(entry.fattr);
619 nfs_free_fhandle(entry.fh); 627 nfs_free_fhandle(entry.fh);
@@ -1083,6 +1091,10 @@ static int nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
1083 if (fhandle == NULL || fattr == NULL) 1091 if (fhandle == NULL || fattr == NULL)
1084 goto out_error; 1092 goto out_error;
1085 1093
1094 label = nfs4_label_alloc(NFS_SERVER(inode), GFP_NOWAIT);
1095 if (IS_ERR(label))
1096 goto out_error;
1097
1086 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, label); 1098 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, label);
1087 if (error) 1099 if (error)
1088 goto out_bad; 1100 goto out_bad;
@@ -1093,6 +1105,8 @@ static int nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
1093 1105
1094 nfs_free_fattr(fattr); 1106 nfs_free_fattr(fattr);
1095 nfs_free_fhandle(fhandle); 1107 nfs_free_fhandle(fhandle);
1108 nfs4_label_free(label);
1109
1096out_set_verifier: 1110out_set_verifier:
1097 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 1111 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
1098 out_valid: 1112 out_valid:
@@ -1109,6 +1123,7 @@ out_zap_parent:
1109 out_bad: 1123 out_bad:
1110 nfs_free_fattr(fattr); 1124 nfs_free_fattr(fattr);
1111 nfs_free_fhandle(fhandle); 1125 nfs_free_fhandle(fhandle);
1126 nfs4_label_free(label);
1112 nfs_mark_for_revalidate(dir); 1127 nfs_mark_for_revalidate(dir);
1113 if (inode && S_ISDIR(inode->i_mode)) { 1128 if (inode && S_ISDIR(inode->i_mode)) {
1114 /* Purge readdir caches. */ 1129 /* Purge readdir caches. */
@@ -1129,6 +1144,7 @@ out_zap_parent:
1129out_error: 1144out_error:
1130 nfs_free_fattr(fattr); 1145 nfs_free_fattr(fattr);
1131 nfs_free_fhandle(fhandle); 1146 nfs_free_fhandle(fhandle);
1147 nfs4_label_free(label);
1132 dput(parent); 1148 dput(parent);
1133 dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) lookup returned error %d\n", 1149 dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) lookup returned error %d\n",
1134 __func__, dentry->d_parent->d_name.name, 1150 __func__, dentry->d_parent->d_name.name,
@@ -1284,6 +1300,10 @@ struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned in
1284 if (fhandle == NULL || fattr == NULL) 1300 if (fhandle == NULL || fattr == NULL)
1285 goto out; 1301 goto out;
1286 1302
1303 label = nfs4_label_alloc(NFS_SERVER(dir), GFP_NOWAIT);
1304 if (IS_ERR(label))
1305 goto out;
1306
1287 parent = dentry->d_parent; 1307 parent = dentry->d_parent;
1288 /* Protect against concurrent sillydeletes */ 1308 /* Protect against concurrent sillydeletes */
1289 nfs_block_sillyrename(parent); 1309 nfs_block_sillyrename(parent);
@@ -1312,6 +1332,7 @@ no_entry:
1312 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 1332 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
1313out_unblock_sillyrename: 1333out_unblock_sillyrename:
1314 nfs_unblock_sillyrename(parent); 1334 nfs_unblock_sillyrename(parent);
1335 nfs4_label_free(label);
1315out: 1336out:
1316 nfs_free_fattr(fattr); 1337 nfs_free_fattr(fattr);
1317 nfs_free_fhandle(fhandle); 1338 nfs_free_fhandle(fhandle);
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 58e7bf876e6c..12e8ad85ae50 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -836,6 +836,13 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
836 goto out; 836 goto out;
837 837
838 nfs_inc_stats(inode, NFSIOS_INODEREVALIDATE); 838 nfs_inc_stats(inode, NFSIOS_INODEREVALIDATE);
839
840 label = nfs4_label_alloc(NFS_SERVER(inode), GFP_KERNEL);
841 if (IS_ERR(label)) {
842 status = PTR_ERR(label);
843 goto out;
844 }
845
839 status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), fattr, label); 846 status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), fattr, label);
840 if (status != 0) { 847 if (status != 0) {
841 dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n", 848 dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n",
@@ -846,7 +853,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
846 if (!S_ISDIR(inode->i_mode)) 853 if (!S_ISDIR(inode->i_mode))
847 set_bit(NFS_INO_STALE, &NFS_I(inode)->flags); 854 set_bit(NFS_INO_STALE, &NFS_I(inode)->flags);
848 } 855 }
849 goto out; 856 goto err_out;
850 } 857 }
851 858
852 status = nfs_refresh_inode(inode, fattr); 859 status = nfs_refresh_inode(inode, fattr);
@@ -854,7 +861,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
854 dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) refresh failed, error=%d\n", 861 dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) refresh failed, error=%d\n",
855 inode->i_sb->s_id, 862 inode->i_sb->s_id,
856 (long long)NFS_FILEID(inode), status); 863 (long long)NFS_FILEID(inode), status);
857 goto out; 864 goto err_out;
858 } 865 }
859 866
860 if (nfsi->cache_validity & NFS_INO_INVALID_ACL) 867 if (nfsi->cache_validity & NFS_INO_INVALID_ACL)
@@ -864,7 +871,9 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
864 inode->i_sb->s_id, 871 inode->i_sb->s_id,
865 (long long)NFS_FILEID(inode)); 872 (long long)NFS_FILEID(inode));
866 873
867 out: 874err_out:
875 nfs4_label_free(label);
876out:
868 nfs_free_fattr(fattr); 877 nfs_free_fattr(fattr);
869 return status; 878 return status;
870} 879}
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 004de2081554..e9488f5e1037 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -833,9 +833,14 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
833 p = kzalloc(sizeof(*p), gfp_mask); 833 p = kzalloc(sizeof(*p), gfp_mask);
834 if (p == NULL) 834 if (p == NULL)
835 goto err; 835 goto err;
836
837 p->f_label = nfs4_label_alloc(server, gfp_mask);
838 if (IS_ERR(p->f_label))
839 goto err_free_p;
840
836 p->o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid, gfp_mask); 841 p->o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid, gfp_mask);
837 if (p->o_arg.seqid == NULL) 842 if (p->o_arg.seqid == NULL)
838 goto err_free; 843 goto err_free_label;
839 nfs_sb_active(dentry->d_sb); 844 nfs_sb_active(dentry->d_sb);
840 p->dentry = dget(dentry); 845 p->dentry = dget(dentry);
841 p->dir = parent; 846 p->dir = parent;
@@ -889,7 +894,10 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
889 nfs4_init_opendata_res(p); 894 nfs4_init_opendata_res(p);
890 kref_init(&p->kref); 895 kref_init(&p->kref);
891 return p; 896 return p;
892err_free: 897
898err_free_label:
899 nfs4_label_free(p->f_label);
900err_free_p:
893 kfree(p); 901 kfree(p);
894err: 902err:
895 dput(parent); 903 dput(parent);
@@ -906,6 +914,9 @@ static void nfs4_opendata_free(struct kref *kref)
906 if (p->state != NULL) 914 if (p->state != NULL)
907 nfs4_put_open_state(p->state); 915 nfs4_put_open_state(p->state);
908 nfs4_put_state_owner(p->owner); 916 nfs4_put_state_owner(p->owner);
917
918 nfs4_label_free(p->f_label);
919
909 dput(p->dir); 920 dput(p->dir);
910 dput(p->dentry); 921 dput(p->dentry);
911 nfs_sb_deactive(sb); 922 nfs_sb_deactive(sb);
@@ -2020,10 +2031,18 @@ static int _nfs4_do_open(struct inode *dir,
2020 if (opendata == NULL) 2031 if (opendata == NULL)
2021 goto err_put_state_owner; 2032 goto err_put_state_owner;
2022 2033
2034 if (label) {
2035 olabel = nfs4_label_alloc(server, GFP_KERNEL);
2036 if (IS_ERR(olabel)) {
2037 status = PTR_ERR(olabel);
2038 goto err_opendata_put;
2039 }
2040 }
2041
2023 if (ctx_th && server->attr_bitmask[2] & FATTR4_WORD2_MDSTHRESHOLD) { 2042 if (ctx_th && server->attr_bitmask[2] & FATTR4_WORD2_MDSTHRESHOLD) {
2024 opendata->f_attr.mdsthreshold = pnfs_mdsthreshold_alloc(); 2043 opendata->f_attr.mdsthreshold = pnfs_mdsthreshold_alloc();
2025 if (!opendata->f_attr.mdsthreshold) 2044 if (!opendata->f_attr.mdsthreshold)
2026 goto err_opendata_put; 2045 goto err_free_label;
2027 opendata->o_arg.open_bitmap = &nfs4_pnfs_open_bitmap[0]; 2046 opendata->o_arg.open_bitmap = &nfs4_pnfs_open_bitmap[0];
2028 } 2047 }
2029 if (dentry->d_inode != NULL) 2048 if (dentry->d_inode != NULL)
@@ -2031,7 +2050,7 @@ static int _nfs4_do_open(struct inode *dir,
2031 2050
2032 status = _nfs4_open_and_get_state(opendata, fmode, flags, &state); 2051 status = _nfs4_open_and_get_state(opendata, fmode, flags, &state);
2033 if (status != 0) 2052 if (status != 0)
2034 goto err_opendata_put; 2053 goto err_free_label;
2035 2054
2036 if ((opendata->o_arg.open_flags & O_EXCL) && 2055 if ((opendata->o_arg.open_flags & O_EXCL) &&
2037 (opendata->o_arg.createmode != NFS4_CREATE_GUARDED)) { 2056 (opendata->o_arg.createmode != NFS4_CREATE_GUARDED)) {
@@ -2053,10 +2072,14 @@ static int _nfs4_do_open(struct inode *dir,
2053 kfree(opendata->f_attr.mdsthreshold); 2072 kfree(opendata->f_attr.mdsthreshold);
2054 opendata->f_attr.mdsthreshold = NULL; 2073 opendata->f_attr.mdsthreshold = NULL;
2055 2074
2075 nfs4_label_free(olabel);
2076
2056 nfs4_opendata_put(opendata); 2077 nfs4_opendata_put(opendata);
2057 nfs4_put_state_owner(sp); 2078 nfs4_put_state_owner(sp);
2058 *res = state; 2079 *res = state;
2059 return 0; 2080 return 0;
2081err_free_label:
2082 nfs4_label_free(olabel);
2060err_opendata_put: 2083err_opendata_put:
2061 kfree(opendata->f_attr.mdsthreshold); 2084 kfree(opendata->f_attr.mdsthreshold);
2062 nfs4_opendata_put(opendata); 2085 nfs4_opendata_put(opendata);
@@ -2670,16 +2693,23 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *mntfh,
2670 return error; 2693 return error;
2671 } 2694 }
2672 2695
2696 label = nfs4_label_alloc(server, GFP_KERNEL);
2697 if (IS_ERR(label))
2698 return PTR_ERR(label);
2699
2673 error = nfs4_proc_getattr(server, mntfh, fattr, label); 2700 error = nfs4_proc_getattr(server, mntfh, fattr, label);
2674 if (error < 0) { 2701 if (error < 0) {
2675 dprintk("nfs4_get_root: getattr error = %d\n", -error); 2702 dprintk("nfs4_get_root: getattr error = %d\n", -error);
2676 return error; 2703 goto err_free_label;
2677 } 2704 }
2678 2705
2679 if (fattr->valid & NFS_ATTR_FATTR_FSID && 2706 if (fattr->valid & NFS_ATTR_FATTR_FSID &&
2680 !nfs_fsid_equal(&server->fsid, &fattr->fsid)) 2707 !nfs_fsid_equal(&server->fsid, &fattr->fsid))
2681 memcpy(&server->fsid, &fattr->fsid, sizeof(server->fsid)); 2708 memcpy(&server->fsid, &fattr->fsid, sizeof(server->fsid));
2682 2709
2710err_free_label:
2711 nfs4_label_free(label);
2712
2683 return error; 2713 return error;
2684} 2714}
2685 2715
@@ -2785,6 +2815,7 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
2785 struct inode *inode = dentry->d_inode; 2815 struct inode *inode = dentry->d_inode;
2786 struct rpc_cred *cred = NULL; 2816 struct rpc_cred *cred = NULL;
2787 struct nfs4_state *state = NULL; 2817 struct nfs4_state *state = NULL;
2818 struct nfs4_label *label = NULL;
2788 int status; 2819 int status;
2789 2820
2790 if (pnfs_ld_layoutret_on_setattr(inode)) 2821 if (pnfs_ld_layoutret_on_setattr(inode))
@@ -2811,9 +2842,15 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
2811 } 2842 }
2812 } 2843 }
2813 2844
2814 status = nfs4_do_setattr(inode, cred, fattr, sattr, state, NULL, NULL); 2845 label = nfs4_label_alloc(NFS_SERVER(inode), GFP_KERNEL);
2846 if (IS_ERR(label))
2847 return PTR_ERR(label);
2848
2849 status = nfs4_do_setattr(inode, cred, fattr, sattr, state, NULL, label);
2815 if (status == 0) 2850 if (status == 0)
2816 nfs_setattr_update_inode(inode, sattr); 2851 nfs_setattr_update_inode(inode, sattr);
2852
2853 nfs4_label_free(label);
2817 return status; 2854 return status;
2818} 2855}
2819 2856
@@ -3193,7 +3230,7 @@ static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
3193 .rpc_resp = &res, 3230 .rpc_resp = &res,
3194 }; 3231 };
3195 int status = -ENOMEM; 3232 int status = -ENOMEM;
3196 3233
3197 status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1); 3234 status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);
3198 if (!status) { 3235 if (!status) {
3199 update_changeattr(old_dir, &res.old_cinfo); 3236 update_changeattr(old_dir, &res.old_cinfo);
@@ -3240,11 +3277,21 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *
3240 if (res.fattr == NULL) 3277 if (res.fattr == NULL)
3241 goto out; 3278 goto out;
3242 3279
3280 res.label = nfs4_label_alloc(server, GFP_KERNEL);
3281 if (IS_ERR(res.label)) {
3282 status = PTR_ERR(res.label);
3283 goto out;
3284 }
3285
3243 status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1); 3286 status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);
3244 if (!status) { 3287 if (!status) {
3245 update_changeattr(dir, &res.cinfo); 3288 update_changeattr(dir, &res.cinfo);
3246 nfs_post_op_update_inode(inode, res.fattr); 3289 nfs_post_op_update_inode(inode, res.fattr);
3247 } 3290 }
3291
3292
3293 nfs4_label_free(res.label);
3294
3248out: 3295out:
3249 nfs_free_fattr(res.fattr); 3296 nfs_free_fattr(res.fattr);
3250 return status; 3297 return status;
@@ -3280,6 +3327,10 @@ static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir,
3280 if (data != NULL) { 3327 if (data != NULL) {
3281 struct nfs_server *server = NFS_SERVER(dir); 3328 struct nfs_server *server = NFS_SERVER(dir);
3282 3329
3330 data->label = nfs4_label_alloc(server, GFP_KERNEL);
3331 if (IS_ERR(data->label))
3332 goto out_free;
3333
3283 data->msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE]; 3334 data->msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE];
3284 data->msg.rpc_argp = &data->arg; 3335 data->msg.rpc_argp = &data->arg;
3285 data->msg.rpc_resp = &data->res; 3336 data->msg.rpc_resp = &data->res;
@@ -3296,6 +3347,9 @@ static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir,
3296 nfs_fattr_init(data->res.fattr); 3347 nfs_fattr_init(data->res.fattr);
3297 } 3348 }
3298 return data; 3349 return data;
3350out_free:
3351 kfree(data);
3352 return NULL;
3299} 3353}
3300 3354
3301static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_createdata *data) 3355static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_createdata *data)
@@ -3311,6 +3365,7 @@ static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_
3311 3365
3312static void nfs4_free_createdata(struct nfs4_createdata *data) 3366static void nfs4_free_createdata(struct nfs4_createdata *data)
3313{ 3367{
3368 nfs4_label_free(data->label);
3314 kfree(data); 3369 kfree(data);
3315} 3370}
3316 3371