Print this page
7378 exported_lock held during nfs4 compound processing


 175          * etc.), then return attrs for stub instead of VROOT object.
 176          * If it fails for any other reason, then return the error.
 177          */
 178         if (error = VOP_FID(vp, &fid, NULL)) {
 179                 if (ismntpt == 0) {
 180                         VN_RELE(vp);
 181                         return (error);
 182                 }
 183 
 184                 if (error != ENOSYS && error != ENOTSUP) {
 185                         VN_RELE(vp);
 186                         VN_RELE(pre_tvp);
 187                         return (error);
 188                 }
 189                 /* go back to vnode that is "under" mount */
 190                 VN_RELE(vp);
 191                 *vpp = pre_tvp;
 192                 return (0);
 193         }
 194 
 195         newexi = checkexport4(&vp->v_vfsp->vfs_fsid, &fid, vp);
 196         if (newexi == NULL) {
 197                 if (ismntpt == 0) {
 198                         *vpp = vp;
 199                 } else {
 200                         VN_RELE(vp);
 201                         *vpp = pre_tvp;
 202                 }
 203                 return (0);
 204         }
 205 
 206         if (ismntpt)
 207                 VN_RELE(pre_tvp);
 208 
 209         /* Save the exi and present the new one to checkauth4() */
 210         saveexi = cs->exi;
 211         cs->exi = newexi;
 212 
 213         /* Get the right cred like lookup does */
 214         scr = cs->cr;
 215         cs->cr = crdup(cs->basecr);
 216 
 217         status = call_checkauth4(cs, req);
 218 
 219         crfree(cs->cr);
 220         cs->cr = scr;
 221         cs->exi = saveexi;
 222 
 223         /* Reset what call_checkauth4() may have set */
 224         *cs->statusp = NFS4_OK;
 225 
 226         if (status != NFS4_OK) {
 227                 VN_RELE(vp);

 228                 if (status == NFS4ERR_DELAY)
 229                         status = NFS4ERR_ACCESS;
 230                 return (status);
 231         }
 232         *vpp = vp;
 233         *exi = newexi;
 234 
 235         return (0);
 236 }
 237 
 238 /* This is the set of pathconf data for vfs */
 239 typedef struct {
 240         uint64_t maxfilesize;
 241         uint32_t maxlink;
 242         uint32_t maxname;
 243 } rfs4_pc_encode_t;
 244 
 245 
 246 static int
 247 rfs4_get_pc_encode(vnode_t *vp, rfs4_pc_encode_t *pce, bitmap4 ar, cred_t *cr)


 678                 resp->data_len = (char *)ptr - (char *)beginning_ptr;
 679                 resp->mblk->b_wptr += resp->data_len;
 680                 kmem_free((caddr_t)rddir_data, rddir_data_len);
 681                 *cs->statusp = resp->status = NFS4_OK;
 682                 goto out;
 683         }
 684 
 685         lastentry_ptr = ptr;
 686         no_space = 0;
 687         for (dp = (struct dirent64 *)rddir_data;
 688             !no_space && rddir_result_size > 0; dp = nextdp(dp)) {
 689 
 690                 /* reset expseudo */
 691                 expseudo = 0;
 692 
 693                 if (vp) {
 694                         VN_RELE(vp);
 695                         vp = NULL;
 696                 }
 697 
 698                 if (newexi)

 699                         newexi = NULL;

 700 
 701                 rddir_result_size -= dp->d_reclen;
 702 
 703                 /* skip "." and ".." entries */
 704                 if (dp->d_ino == 0 || NFS_IS_DOTNAME(dp->d_name)) {
 705                         rddir_next_offset = dp->d_off;
 706                         continue;
 707                 }
 708 
 709                 if (check_visible &&
 710                     !nfs_visible_inode(cs->exi, dp->d_ino, &expseudo)) {
 711                         rddir_next_offset = dp->d_off;
 712                         continue;
 713                 }
 714 
 715                 /*
 716                  * Only if the client requested attributes...
 717                  * If the VOP_LOOKUP fails ENOENT, then skip this entry
 718                  * for the readdir response.  If there was another error,
 719                  * then set the rddirattr_error and the error will be


1473                  * If there was trouble obtaining a mapping for either
1474                  * the owner or group attributes, then remove them from
1475                  * bitmap4 for this entry and reset the bitmap value
1476                  * in the data stream.
1477                  */
1478                 if (owner_error || group_error) {
1479                         if (owner_error)
1480                                 ae &= ~FATTR4_OWNER_MASK;
1481                         if (group_error)
1482                                 ae &= ~FATTR4_OWNER_GROUP_MASK;
1483                         IXDR_PUT_HYPER(attrmask_ptr, ae);
1484                 }
1485 
1486                 /* END OF ATTRIBUTE ENCODING */
1487 
1488                 lastentry_ptr = ptr;
1489                 nents++;
1490                 rddir_next_offset = dp->d_off;
1491         }
1492 





1493         /*
1494          * Check for the case that another VOP_READDIR() has to be done.
1495          * - no space encoding error
1496          * - no entry successfully encoded
1497          * - still more directory to read
1498          */
1499         if (!no_space && nents == 0 && !iseofdir)
1500                 goto readagain;
1501 
1502         *cs->statusp = resp->status = NFS4_OK;
1503 
1504         /*
1505          * If no_space is set then we terminated prematurely,
1506          * rewind to the last entry and this can never be EOF.
1507          */
1508         if (no_space) {
1509                 ptr = lastentry_ptr;
1510                 eof = FALSE; /* ended encoded prematurely */
1511         } else {
1512                 eof = (iseofdir ? TRUE : FALSE);




 175          * etc.), then return attrs for stub instead of VROOT object.
 176          * If it fails for any other reason, then return the error.
 177          */
 178         if (error = VOP_FID(vp, &fid, NULL)) {
 179                 if (ismntpt == 0) {
 180                         VN_RELE(vp);
 181                         return (error);
 182                 }
 183 
 184                 if (error != ENOSYS && error != ENOTSUP) {
 185                         VN_RELE(vp);
 186                         VN_RELE(pre_tvp);
 187                         return (error);
 188                 }
 189                 /* go back to vnode that is "under" mount */
 190                 VN_RELE(vp);
 191                 *vpp = pre_tvp;
 192                 return (0);
 193         }
 194 
 195         newexi = checkexport(&vp->v_vfsp->vfs_fsid, &fid, vp);
 196         if (newexi == NULL) {
 197                 if (ismntpt == 0) {
 198                         *vpp = vp;
 199                 } else {
 200                         VN_RELE(vp);
 201                         *vpp = pre_tvp;
 202                 }
 203                 return (0);
 204         }
 205 
 206         if (ismntpt)
 207                 VN_RELE(pre_tvp);
 208 
 209         /* Save the exi and present the new one to checkauth4() */
 210         saveexi = cs->exi;
 211         cs->exi = newexi;
 212 
 213         /* Get the right cred like lookup does */
 214         scr = cs->cr;
 215         cs->cr = crdup(cs->basecr);
 216 
 217         status = call_checkauth4(cs, req);
 218 
 219         crfree(cs->cr);
 220         cs->cr = scr;
 221         cs->exi = saveexi;
 222 
 223         /* Reset what call_checkauth4() may have set */
 224         *cs->statusp = NFS4_OK;
 225 
 226         if (status != NFS4_OK) {
 227                 VN_RELE(vp);
 228                 exi_rele(newexi);
 229                 if (status == NFS4ERR_DELAY)
 230                         status = NFS4ERR_ACCESS;
 231                 return (status);
 232         }
 233         *vpp = vp;
 234         *exi = newexi;
 235 
 236         return (0);
 237 }
 238 
 239 /* This is the set of pathconf data for vfs */
 240 typedef struct {
 241         uint64_t maxfilesize;
 242         uint32_t maxlink;
 243         uint32_t maxname;
 244 } rfs4_pc_encode_t;
 245 
 246 
 247 static int
 248 rfs4_get_pc_encode(vnode_t *vp, rfs4_pc_encode_t *pce, bitmap4 ar, cred_t *cr)


 679                 resp->data_len = (char *)ptr - (char *)beginning_ptr;
 680                 resp->mblk->b_wptr += resp->data_len;
 681                 kmem_free((caddr_t)rddir_data, rddir_data_len);
 682                 *cs->statusp = resp->status = NFS4_OK;
 683                 goto out;
 684         }
 685 
 686         lastentry_ptr = ptr;
 687         no_space = 0;
 688         for (dp = (struct dirent64 *)rddir_data;
 689             !no_space && rddir_result_size > 0; dp = nextdp(dp)) {
 690 
 691                 /* reset expseudo */
 692                 expseudo = 0;
 693 
 694                 if (vp) {
 695                         VN_RELE(vp);
 696                         vp = NULL;
 697                 }
 698 
 699                 if (newexi) {
 700                         exi_rele(newexi);
 701                         newexi = NULL;
 702                 }
 703 
 704                 rddir_result_size -= dp->d_reclen;
 705 
 706                 /* skip "." and ".." entries */
 707                 if (dp->d_ino == 0 || NFS_IS_DOTNAME(dp->d_name)) {
 708                         rddir_next_offset = dp->d_off;
 709                         continue;
 710                 }
 711 
 712                 if (check_visible &&
 713                     !nfs_visible_inode(cs->exi, dp->d_ino, &expseudo)) {
 714                         rddir_next_offset = dp->d_off;
 715                         continue;
 716                 }
 717 
 718                 /*
 719                  * Only if the client requested attributes...
 720                  * If the VOP_LOOKUP fails ENOENT, then skip this entry
 721                  * for the readdir response.  If there was another error,
 722                  * then set the rddirattr_error and the error will be


1476                  * If there was trouble obtaining a mapping for either
1477                  * the owner or group attributes, then remove them from
1478                  * bitmap4 for this entry and reset the bitmap value
1479                  * in the data stream.
1480                  */
1481                 if (owner_error || group_error) {
1482                         if (owner_error)
1483                                 ae &= ~FATTR4_OWNER_MASK;
1484                         if (group_error)
1485                                 ae &= ~FATTR4_OWNER_GROUP_MASK;
1486                         IXDR_PUT_HYPER(attrmask_ptr, ae);
1487                 }
1488 
1489                 /* END OF ATTRIBUTE ENCODING */
1490 
1491                 lastentry_ptr = ptr;
1492                 nents++;
1493                 rddir_next_offset = dp->d_off;
1494         }
1495 
1496         if (newexi) {
1497                 exi_rele(newexi);
1498                 newexi = NULL;
1499         }
1500 
1501         /*
1502          * Check for the case that another VOP_READDIR() has to be done.
1503          * - no space encoding error
1504          * - no entry successfully encoded
1505          * - still more directory to read
1506          */
1507         if (!no_space && nents == 0 && !iseofdir)
1508                 goto readagain;
1509 
1510         *cs->statusp = resp->status = NFS4_OK;
1511 
1512         /*
1513          * If no_space is set then we terminated prematurely,
1514          * rewind to the last entry and this can never be EOF.
1515          */
1516         if (no_space) {
1517                 ptr = lastentry_ptr;
1518                 eof = FALSE; /* ended encoded prematurely */
1519         } else {
1520                 eof = (iseofdir ? TRUE : FALSE);