Print this page
*** NO COMMENTS ***

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/lofi.c
          +++ new/usr/src/uts/common/io/lofi.c
↓ open down ↓ 470 lines elided ↑ open up ↑
 471  471          if (lsp->ls_vp == NULL) {
 472  472                  mutex_exit(&lofi_lock);
 473  473                  return (ENXIO);
 474  474          }
 475  475  
 476  476          if (mark_opened(lsp, otyp) == -1) {
 477  477                  mutex_exit(&lofi_lock);
 478  478                  return (EINVAL);
 479  479          }
 480  480  
      481 +        if (lsp->ls_readonly && (flag & FWRITE)) {
      482 +                mutex_exit(&lofi_lock);
      483 +                return (EROFS);
      484 +        }
      485 +
 481  486          mutex_exit(&lofi_lock);
 482  487          return (0);
 483  488  }
 484  489  
 485  490  /*ARGSUSED*/
 486  491  static int
 487  492  lofi_close(dev_t dev, int flag, int otyp, struct cred *credp)
 488  493  {
 489  494          minor_t minor;
 490  495          struct lofi_state *lsp;
↓ open down ↓ 1122 lines elided ↑ open up ↑
1613 1618          if (INGLOBALZONE(curproc) || lsp->ls_zone.zref_zone == curzone)
1614 1619                  return (0);
1615 1620          return (EPERM);
1616 1621  }
1617 1622  
1618 1623  /*
1619 1624   * Find the lofi state for the given filename. We compare by vnode to
1620 1625   * allow the global zone visibility into NGZ lofi nodes.
1621 1626   */
1622 1627  static int
1623      -file_to_lofi_nocheck(char *filename, struct lofi_state **lspp)
     1628 +file_to_lofi_nocheck(char *filename, boolean_t readonly,
     1629 +    struct lofi_state **lspp)
1624 1630  {
1625 1631          struct lofi_state *lsp;
1626 1632          vnode_t *vp = NULL;
1627 1633          int err = 0;
     1634 +        int rdfiles = 0;
1628 1635  
1629 1636          ASSERT(MUTEX_HELD(&lofi_lock));
1630 1637  
1631 1638          if ((err = lookupname(filename, UIO_SYSSPACE, FOLLOW,
1632 1639              NULLVPP, &vp)) != 0)
1633 1640                  goto out;
1634 1641  
1635 1642          if (vp->v_type == VREG) {
1636 1643                  vnode_t *realvp;
1637 1644                  if (VOP_REALVP(vp, &realvp, NULL) == 0) {
↓ open down ↓ 1 lines elided ↑ open up ↑
1639 1646                          VN_RELE(vp);
1640 1647                          vp = realvp;
1641 1648                  }
1642 1649          }
1643 1650  
1644 1651          for (lsp = list_head(&lofi_list); lsp != NULL;
1645 1652              lsp = list_next(&lofi_list, lsp)) {
1646 1653                  if (lsp->ls_vp == vp) {
1647 1654                          if (lspp != NULL)
1648 1655                                  *lspp = lsp;
     1656 +                        if (lsp->ls_readonly) {
     1657 +                                rdfiles++;
     1658 +                                /* Skip if '-r' is specified */
     1659 +                                if (readonly)
     1660 +                                        continue;
     1661 +                        }
1649 1662                          goto out;
1650 1663                  }
1651 1664          }
1652 1665  
1653 1666          err = ENOENT;
1654 1667  
     1668 +        /*
     1669 +         * If a filename is given as an argument for lofi_unmap, we shouldn't
     1670 +         * allow unmap if there are multiple read-only lofi devices associated
     1671 +         * with this file.
     1672 +         */
     1673 +        if (lspp != NULL) {
     1674 +                if (rdfiles == 1)
     1675 +                        err = 0;
     1676 +                else if (rdfiles > 1)
     1677 +                        err = EBUSY;
     1678 +        }
     1679 +
1655 1680  out:
1656 1681          if (vp != NULL)
1657 1682                  VN_RELE(vp);
1658 1683          return (err);
1659 1684  }
1660 1685  
1661 1686  /*
1662 1687   * Find the minor for the given filename, checking the zone can access
1663 1688   * it.
1664 1689   */
1665 1690  static int
1666      -file_to_lofi(char *filename, struct lofi_state **lspp)
     1691 +file_to_lofi(char *filename, boolean_t readonly, struct lofi_state **lspp)
1667 1692  {
1668 1693          int err = 0;
1669 1694  
1670 1695          ASSERT(MUTEX_HELD(&lofi_lock));
1671 1696  
1672      -        if ((err = file_to_lofi_nocheck(filename, lspp)) != 0)
     1697 +        if ((err = file_to_lofi_nocheck(filename, readonly, lspp)) != 0)
1673 1698                  return (err);
1674 1699  
1675 1700          if ((err = lofi_access(*lspp)) != 0)
1676 1701                  return (err);
1677 1702  
1678 1703          return (0);
1679 1704  }
1680 1705  
1681 1706  /*
1682 1707   * Fakes up a disk geometry, and one big partition, based on the size
↓ open down ↓ 432 lines elided ↑ open up ↑
2115 2140  
2116 2141          mutex_enter(&curproc->p_lock);
2117 2142          if ((error = rctl_incr_lofi(curproc, curproc->p_zone, 1)) != 0) {
2118 2143                  mutex_exit(&curproc->p_lock);
2119 2144                  mutex_exit(&lofi_lock);
2120 2145                  free_lofi_ioctl(klip);
2121 2146                  return (error);
2122 2147          }
2123 2148          mutex_exit(&curproc->p_lock);
2124 2149  
2125      -        if (file_to_lofi_nocheck(klip->li_filename, NULL) == 0) {
     2150 +        if (file_to_lofi_nocheck(klip->li_filename, klip->li_readonly,
     2151 +            NULL) == 0) {
2126 2152                  error = EBUSY;
2127 2153                  goto err;
2128 2154          }
2129 2155  
2130 2156          if (pickminor) {
2131 2157                  minor = (minor_t)id_allocff_nosleep(lofi_minor_id);
2132 2158                  if (minor == (minor_t)-1) {
2133 2159                          error = EAGAIN;
2134 2160                          goto err;
2135 2161                  }
↓ open down ↓ 100 lines elided ↑ open up ↑
2236 2262              NULL, "disk", KSTAT_TYPE_IO, 1, 0, getzoneid());
2237 2263  
2238 2264          if (lsp->ls_kstat == NULL) {
2239 2265                  error = ENOMEM;
2240 2266                  goto err;
2241 2267          }
2242 2268  
2243 2269          lsp->ls_kstat->ks_lock = &lsp->ls_kstat_lock;
2244 2270          kstat_zone_add(lsp->ls_kstat, GLOBAL_ZONEID);
2245 2271  
     2272 +        lsp->ls_readonly = klip->li_readonly;
     2273 +
2246 2274          if ((error = lofi_init_crypto(lsp, klip)) != 0)
2247 2275                  goto err;
2248 2276  
2249 2277          if ((error = lofi_init_compress(lsp)) != 0)
2250 2278                  goto err;
2251 2279  
2252 2280          fake_disk_geometry(lsp);
2253 2281  
2254 2282          /* create minor nodes */
2255 2283  
↓ open down ↓ 80 lines elided ↑ open up ↑
2336 2364          struct lofi_state *lsp;
2337 2365          struct lofi_ioctl *klip;
2338 2366          int err;
2339 2367  
2340 2368          err = copy_in_lofi_ioctl(ulip, &klip, ioctl_flag);
2341 2369          if (err != 0)
2342 2370                  return (err);
2343 2371  
2344 2372          mutex_enter(&lofi_lock);
2345 2373          if (byfilename) {
2346      -                if ((err = file_to_lofi(klip->li_filename, &lsp)) != 0) {
     2374 +                if ((err = file_to_lofi(klip->li_filename, klip->li_readonly,
     2375 +                    &lsp)) != 0) {
2347 2376                          mutex_exit(&lofi_lock);
2348 2377                          return (err);
2349 2378                  }
2350 2379          } else if (klip->li_minor == 0) {
2351 2380                  mutex_exit(&lofi_lock);
2352 2381                  free_lofi_ioctl(klip);
2353 2382                  return (ENXIO);
2354 2383          } else {
2355 2384                  lsp = ddi_get_soft_state(lofi_statep, klip->li_minor);
2356 2385          }
↓ open down ↓ 96 lines elided ↑ open up ↑
2453 2482                  /*
2454 2483                   * This may fail if, for example, we're trying to look
2455 2484                   * up a zoned NFS path from the global zone.
2456 2485                   */
2457 2486                  if (vnodetopath(NULL, lsp->ls_stacked_vp, klip->li_filename,
2458 2487                      sizeof (klip->li_filename), CRED()) != 0) {
2459 2488                          (void) strlcpy(klip->li_filename, "?",
2460 2489                              sizeof (klip->li_filename));
2461 2490                  }
2462 2491  
     2492 +                klip->li_readonly = lsp->ls_readonly;
     2493 +
2463 2494                  (void) strlcpy(klip->li_algorithm, lsp->ls_comp_algorithm,
2464 2495                      sizeof (klip->li_algorithm));
2465 2496                  klip->li_crypto_enabled = lsp->ls_crypto_enabled;
2466 2497                  mutex_exit(&lofi_lock);
2467 2498                  error = copy_out_lofi_ioctl(klip, ulip, ioctl_flag);
2468 2499                  free_lofi_ioctl(klip);
2469 2500                  return (error);
2470 2501          case LOFI_GET_MINOR:
2471 2502                  mutex_enter(&lofi_lock);
2472      -                error = file_to_lofi(klip->li_filename, &lsp);
     2503 +                error = file_to_lofi(klip->li_filename,
     2504 +                    klip->li_readonly, &lsp);
2473 2505                  if (error == 0)
2474 2506                          klip->li_minor = getminor(lsp->ls_dev);
2475 2507                  mutex_exit(&lofi_lock);
2476 2508  
2477 2509                  if (error == 0)
2478 2510                          error = copy_out_lofi_ioctl(klip, ulip, ioctl_flag);
2479 2511  
2480 2512                  free_lofi_ioctl(klip);
2481 2513                  return (error);
2482 2514          case LOFI_CHECK_COMPRESSED:
2483 2515                  mutex_enter(&lofi_lock);
2484      -                error = file_to_lofi(klip->li_filename, &lsp);
     2516 +                error = file_to_lofi(klip->li_filename,
     2517 +                    klip->li_readonly, &lsp);
2485 2518                  if (error != 0) {
2486 2519                          mutex_exit(&lofi_lock);
2487 2520                          free_lofi_ioctl(klip);
2488 2521                          return (error);
2489 2522                  }
2490 2523  
2491 2524                  klip->li_minor = getminor(lsp->ls_dev);
2492 2525                  (void) strlcpy(klip->li_algorithm, lsp->ls_comp_algorithm,
2493 2526                      sizeof (klip->li_algorithm));
2494 2527  
↓ open down ↓ 286 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX