74 typedef struct nfs3_srv {
75 writeverf3 write3verf;
76 } nfs3_srv_t;
77
78 /*
79 * These are the interface routines for the server side of the
80 * Network File System. See the NFS version 3 protocol specification
81 * for a description of this interface.
82 */
83
84 static int sattr3_to_vattr(sattr3 *, struct vattr *);
85 static int vattr_to_fattr3(struct vattr *, fattr3 *);
86 static int vattr_to_wcc_attr(struct vattr *, wcc_attr *);
87 static void vattr_to_pre_op_attr(struct vattr *, pre_op_attr *);
88 static void vattr_to_wcc_data(struct vattr *, struct vattr *, wcc_data *);
89 static int rdma_setup_read_data3(READ3args *, READ3resok *);
90
91 extern int nfs_loaned_buffers;
92
93 u_longlong_t nfs3_srv_caller_id;
94 static zone_key_t rfs3_zone_key;
95
96 /* ARGSUSED */
97 void
98 rfs3_getattr(GETATTR3args *args, GETATTR3res *resp, struct exportinfo *exi,
99 struct svc_req *req, cred_t *cr, bool_t ro)
100 {
101 int error;
102 vnode_t *vp;
103 struct vattr va;
104
105 vp = nfs3_fhtovp(&args->object, exi);
106
107 DTRACE_NFSV3_5(op__getattr__start, struct svc_req *, req,
108 cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
109 GETATTR3args *, args);
110
111 if (vp == NULL) {
112 error = ESTALE;
113 goto out;
114 }
115
1310 struct iovec *iovp;
1311 int iovcnt;
1312 int ioflag;
1313 cred_t *savecred;
1314 int in_crit = 0;
1315 int rwlock_ret = -1;
1316 caller_context_t ct;
1317
1318 vp = nfs3_fhtovp(&args->file, exi);
1319
1320 DTRACE_NFSV3_5(op__write__start, struct svc_req *, req,
1321 cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
1322 WRITE3args *, args);
1323
1324 if (vp == NULL) {
1325 error = ESTALE;
1326 goto err;
1327 }
1328
1329 ASSERT3P(curzone, ==, exi->exi_zone); /* exi is guaranteed non-NULL. */
1330 ns = zone_getspecific(rfs3_zone_key, curzone);
1331 if (is_system_labeled()) {
1332 bslabel_t *clabel = req->rq_label;
1333
1334 ASSERT(clabel != NULL);
1335 DTRACE_PROBE2(tx__rfs3__log__info__opwrite__clabel, char *,
1336 "got client label from request(1)", struct svc_req *, req);
1337
1338 if (!blequal(&l_admin_low->tsl_label, clabel)) {
1339 if (!do_rfs_label_check(clabel, vp, EQUALITY_CHECK,
1340 exi)) {
1341 resp->status = NFS3ERR_ACCES;
1342 goto err1;
1343 }
1344 }
1345 }
1346
1347 ct.cc_sysid = 0;
1348 ct.cc_pid = 0;
1349 ct.cc_caller_id = nfs3_srv_caller_id;
1350 ct.cc_flags = CC_DONTBLOCK;
4111 struct vattr *bvap;
4112 struct vattr bva;
4113 struct vattr *avap;
4114 struct vattr ava;
4115
4116 bvap = NULL;
4117 avap = NULL;
4118
4119 vp = nfs3_fhtovp(&args->file, exi);
4120
4121 DTRACE_NFSV3_5(op__commit__start, struct svc_req *, req,
4122 cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
4123 COMMIT3args *, args);
4124
4125 if (vp == NULL) {
4126 error = ESTALE;
4127 goto out;
4128 }
4129
4130 ASSERT3P(curzone, ==, exi->exi_zone); /* exi is guaranteed non-NULL. */
4131 ns = zone_getspecific(rfs3_zone_key, curzone);
4132 bva.va_mask = AT_ALL;
4133 error = VOP_GETATTR(vp, &bva, 0, cr, NULL);
4134
4135 /*
4136 * If we can't get the attributes, then we can't do the
4137 * right access checking. So, we'll fail the request.
4138 */
4139 if (error)
4140 goto out;
4141
4142 bvap = &bva;
4143
4144 if (rdonly(ro, vp)) {
4145 resp->status = NFS3ERR_ROFS;
4146 goto out1;
4147 }
4148
4149 if (vp->v_type != VREG) {
4150 resp->status = NFS3ERR_INVAL;
4151 goto out1;
4364 vattr_to_post_op_attr(avap, &wccp->after);
4365 }
4366
4367 static int
4368 rdma_setup_read_data3(READ3args *args, READ3resok *rok)
4369 {
4370 struct clist *wcl;
4371 int wlist_len;
4372 count3 count = rok->count;
4373
4374 wcl = args->wlist;
4375 if (rdma_setup_read_chunks(wcl, count, &wlist_len) == FALSE)
4376 return (FALSE);
4377
4378 wcl = args->wlist;
4379 rok->wlist_len = wlist_len;
4380 rok->wlist = wcl;
4381 return (TRUE);
4382 }
4383
4384 /* ARGSUSED */
4385 static void *
4386 rfs3_zone_init(zoneid_t zoneid)
4387 {
4388 nfs3_srv_t *ns;
4389 struct rfs3_verf_overlay {
4390 uint_t id; /* a "unique" identifier */
4391 int ts; /* a unique timestamp */
4392 } *verfp;
4393 timestruc_t now;
4394
4395 ns = kmem_zalloc(sizeof (*ns), KM_SLEEP);
4396
4397 /*
4398 * The following algorithm attempts to find a unique verifier
4399 * to be used as the write verifier returned from the server
4400 * to the client. It is important that this verifier change
4401 * whenever the server reboots. Of secondary importance, it
4402 * is important for the verifier to be unique between two
4403 * different servers.
4404 *
4405 * Thus, an attempt is made to use the system hostid and the
4406 * current time in seconds when the nfssrv kernel module is
4411 * time the server reboots and minimize the chances that two
4412 * different servers will have the same verifier.
4413 */
4414
4415 #ifndef lint
4416 /*
4417 * We ASSERT that this constant logic expression is
4418 * always true because in the past, it wasn't.
4419 */
4420 ASSERT(sizeof (*verfp) <= sizeof (ns->write3verf));
4421 #endif
4422
4423 gethrestime(&now);
4424 verfp = (struct rfs3_verf_overlay *)&ns->write3verf;
4425 verfp->ts = (int)now.tv_sec;
4426 verfp->id = zone_get_hostid(NULL);
4427
4428 if (verfp->id == 0)
4429 verfp->id = (uint_t)now.tv_nsec;
4430
4431 return (ns);
4432 }
4433
4434 /* ARGSUSED */
4435 static void
4436 rfs3_zone_fini(zoneid_t zoneid, void *data)
4437 {
4438 nfs3_srv_t *ns = data;
4439
4440 kmem_free(ns, sizeof (*ns));
4441 }
4442
4443 void
4444 rfs3_srvrinit(void)
4445 {
4446 nfs3_srv_caller_id = fs_new_caller_id();
4447 zone_key_create(&rfs3_zone_key, rfs3_zone_init, NULL, rfs3_zone_fini);
4448 }
4449
4450 void
4451 rfs3_srvrfini(void)
4452 {
4453 /* Nothing to do */
4454 }
|
74 typedef struct nfs3_srv {
75 writeverf3 write3verf;
76 } nfs3_srv_t;
77
78 /*
79 * These are the interface routines for the server side of the
80 * Network File System. See the NFS version 3 protocol specification
81 * for a description of this interface.
82 */
83
84 static int sattr3_to_vattr(sattr3 *, struct vattr *);
85 static int vattr_to_fattr3(struct vattr *, fattr3 *);
86 static int vattr_to_wcc_attr(struct vattr *, wcc_attr *);
87 static void vattr_to_pre_op_attr(struct vattr *, pre_op_attr *);
88 static void vattr_to_wcc_data(struct vattr *, struct vattr *, wcc_data *);
89 static int rdma_setup_read_data3(READ3args *, READ3resok *);
90
91 extern int nfs_loaned_buffers;
92
93 u_longlong_t nfs3_srv_caller_id;
94
95 static nfs3_srv_t *
96 nfs3_get_srv(void)
97 {
98 nfs_globals_t *ng = zone_getspecific(nfssrv_zone_key, curzone);
99 nfs3_srv_t *srv = ng->nfs3_srv;
100 ASSERT(srv != NULL);
101 return (srv);
102 }
103
104 /* ARGSUSED */
105 void
106 rfs3_getattr(GETATTR3args *args, GETATTR3res *resp, struct exportinfo *exi,
107 struct svc_req *req, cred_t *cr, bool_t ro)
108 {
109 int error;
110 vnode_t *vp;
111 struct vattr va;
112
113 vp = nfs3_fhtovp(&args->object, exi);
114
115 DTRACE_NFSV3_5(op__getattr__start, struct svc_req *, req,
116 cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
117 GETATTR3args *, args);
118
119 if (vp == NULL) {
120 error = ESTALE;
121 goto out;
122 }
123
1318 struct iovec *iovp;
1319 int iovcnt;
1320 int ioflag;
1321 cred_t *savecred;
1322 int in_crit = 0;
1323 int rwlock_ret = -1;
1324 caller_context_t ct;
1325
1326 vp = nfs3_fhtovp(&args->file, exi);
1327
1328 DTRACE_NFSV3_5(op__write__start, struct svc_req *, req,
1329 cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
1330 WRITE3args *, args);
1331
1332 if (vp == NULL) {
1333 error = ESTALE;
1334 goto err;
1335 }
1336
1337 ASSERT3P(curzone, ==, exi->exi_zone); /* exi is guaranteed non-NULL. */
1338 ns = nfs3_get_srv();
1339
1340 if (is_system_labeled()) {
1341 bslabel_t *clabel = req->rq_label;
1342
1343 ASSERT(clabel != NULL);
1344 DTRACE_PROBE2(tx__rfs3__log__info__opwrite__clabel, char *,
1345 "got client label from request(1)", struct svc_req *, req);
1346
1347 if (!blequal(&l_admin_low->tsl_label, clabel)) {
1348 if (!do_rfs_label_check(clabel, vp, EQUALITY_CHECK,
1349 exi)) {
1350 resp->status = NFS3ERR_ACCES;
1351 goto err1;
1352 }
1353 }
1354 }
1355
1356 ct.cc_sysid = 0;
1357 ct.cc_pid = 0;
1358 ct.cc_caller_id = nfs3_srv_caller_id;
1359 ct.cc_flags = CC_DONTBLOCK;
4120 struct vattr *bvap;
4121 struct vattr bva;
4122 struct vattr *avap;
4123 struct vattr ava;
4124
4125 bvap = NULL;
4126 avap = NULL;
4127
4128 vp = nfs3_fhtovp(&args->file, exi);
4129
4130 DTRACE_NFSV3_5(op__commit__start, struct svc_req *, req,
4131 cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
4132 COMMIT3args *, args);
4133
4134 if (vp == NULL) {
4135 error = ESTALE;
4136 goto out;
4137 }
4138
4139 ASSERT3P(curzone, ==, exi->exi_zone); /* exi is guaranteed non-NULL. */
4140 ns = nfs3_get_srv();
4141 bva.va_mask = AT_ALL;
4142 error = VOP_GETATTR(vp, &bva, 0, cr, NULL);
4143
4144 /*
4145 * If we can't get the attributes, then we can't do the
4146 * right access checking. So, we'll fail the request.
4147 */
4148 if (error)
4149 goto out;
4150
4151 bvap = &bva;
4152
4153 if (rdonly(ro, vp)) {
4154 resp->status = NFS3ERR_ROFS;
4155 goto out1;
4156 }
4157
4158 if (vp->v_type != VREG) {
4159 resp->status = NFS3ERR_INVAL;
4160 goto out1;
4373 vattr_to_post_op_attr(avap, &wccp->after);
4374 }
4375
4376 static int
4377 rdma_setup_read_data3(READ3args *args, READ3resok *rok)
4378 {
4379 struct clist *wcl;
4380 int wlist_len;
4381 count3 count = rok->count;
4382
4383 wcl = args->wlist;
4384 if (rdma_setup_read_chunks(wcl, count, &wlist_len) == FALSE)
4385 return (FALSE);
4386
4387 wcl = args->wlist;
4388 rok->wlist_len = wlist_len;
4389 rok->wlist = wcl;
4390 return (TRUE);
4391 }
4392
4393 void
4394 rfs3_srv_zone_init(nfs_globals_t *ng)
4395 {
4396 nfs3_srv_t *ns;
4397 struct rfs3_verf_overlay {
4398 uint_t id; /* a "unique" identifier */
4399 int ts; /* a unique timestamp */
4400 } *verfp;
4401 timestruc_t now;
4402
4403 ns = kmem_zalloc(sizeof (*ns), KM_SLEEP);
4404
4405 /*
4406 * The following algorithm attempts to find a unique verifier
4407 * to be used as the write verifier returned from the server
4408 * to the client. It is important that this verifier change
4409 * whenever the server reboots. Of secondary importance, it
4410 * is important for the verifier to be unique between two
4411 * different servers.
4412 *
4413 * Thus, an attempt is made to use the system hostid and the
4414 * current time in seconds when the nfssrv kernel module is
4419 * time the server reboots and minimize the chances that two
4420 * different servers will have the same verifier.
4421 */
4422
4423 #ifndef lint
4424 /*
4425 * We ASSERT that this constant logic expression is
4426 * always true because in the past, it wasn't.
4427 */
4428 ASSERT(sizeof (*verfp) <= sizeof (ns->write3verf));
4429 #endif
4430
4431 gethrestime(&now);
4432 verfp = (struct rfs3_verf_overlay *)&ns->write3verf;
4433 verfp->ts = (int)now.tv_sec;
4434 verfp->id = zone_get_hostid(NULL);
4435
4436 if (verfp->id == 0)
4437 verfp->id = (uint_t)now.tv_nsec;
4438
4439 ng->nfs3_srv = ns;
4440 }
4441
4442 void
4443 rfs3_srv_zone_fini(nfs_globals_t *ng)
4444 {
4445 nfs3_srv_t *ns = ng->nfs3_srv;
4446
4447 ng->nfs3_srv = NULL;
4448
4449 kmem_free(ns, sizeof (*ns));
4450 }
4451
4452 void
4453 rfs3_srvrinit(void)
4454 {
4455 nfs3_srv_caller_id = fs_new_caller_id();
4456 }
4457
4458 void
4459 rfs3_srvrfini(void)
4460 {
4461 /* Nothing to do */
4462 }
|