Print this page
*** NO COMMENTS ***

*** 476,486 **** --- 476,491 ---- if (mark_opened(lsp, otyp) == -1) { mutex_exit(&lofi_lock); return (EINVAL); } + if (lsp->ls_readonly && (flag & FWRITE)) { mutex_exit(&lofi_lock); + return (EROFS); + } + + mutex_exit(&lofi_lock); return (0); } /*ARGSUSED*/ static int
*** 1618,1632 **** /* * Find the lofi state for the given filename. We compare by vnode to * allow the global zone visibility into NGZ lofi nodes. */ static int ! file_to_lofi_nocheck(char *filename, struct lofi_state **lspp) { struct lofi_state *lsp; vnode_t *vp = NULL; int err = 0; ASSERT(MUTEX_HELD(&lofi_lock)); if ((err = lookupname(filename, UIO_SYSSPACE, FOLLOW, NULLVPP, &vp)) != 0) --- 1623,1639 ---- /* * Find the lofi state for the given filename. We compare by vnode to * allow the global zone visibility into NGZ lofi nodes. */ static int ! file_to_lofi_nocheck(char *filename, boolean_t readonly, ! struct lofi_state **lspp) { struct lofi_state *lsp; vnode_t *vp = NULL; int err = 0; + int rdfiles = 0; ASSERT(MUTEX_HELD(&lofi_lock)); if ((err = lookupname(filename, UIO_SYSSPACE, FOLLOW, NULLVPP, &vp)) != 0)
*** 1644,1659 **** --- 1651,1684 ---- for (lsp = list_head(&lofi_list); lsp != NULL; lsp = list_next(&lofi_list, lsp)) { if (lsp->ls_vp == vp) { if (lspp != NULL) *lspp = lsp; + if (lsp->ls_readonly) { + rdfiles++; + /* Skip if '-r' is specified */ + if (readonly) + continue; + } goto out; } } err = ENOENT; + /* + * If a filename is given as an argument for lofi_unmap, we shouldn't + * allow unmap if there are multiple read-only lofi devices associated + * with this file. + */ + if (lspp != NULL) { + if (rdfiles == 1) + err = 0; + else if (rdfiles > 1) + err = EBUSY; + } + out: if (vp != NULL) VN_RELE(vp); return (err); }
*** 1661,1677 **** /* * Find the minor for the given filename, checking the zone can access * it. */ static int ! file_to_lofi(char *filename, struct lofi_state **lspp) { int err = 0; ASSERT(MUTEX_HELD(&lofi_lock)); ! if ((err = file_to_lofi_nocheck(filename, lspp)) != 0) return (err); if ((err = lofi_access(*lspp)) != 0) return (err); --- 1686,1702 ---- /* * Find the minor for the given filename, checking the zone can access * it. */ static int ! file_to_lofi(char *filename, boolean_t readonly, struct lofi_state **lspp) { int err = 0; ASSERT(MUTEX_HELD(&lofi_lock)); ! if ((err = file_to_lofi_nocheck(filename, readonly, lspp)) != 0) return (err); if ((err = lofi_access(*lspp)) != 0) return (err);
*** 2120,2130 **** free_lofi_ioctl(klip); return (error); } mutex_exit(&curproc->p_lock); ! if (file_to_lofi_nocheck(klip->li_filename, NULL) == 0) { error = EBUSY; goto err; } if (pickminor) { --- 2145,2156 ---- free_lofi_ioctl(klip); return (error); } mutex_exit(&curproc->p_lock); ! if (file_to_lofi_nocheck(klip->li_filename, klip->li_readonly, ! NULL) == 0) { error = EBUSY; goto err; } if (pickminor) {
*** 2241,2250 **** --- 2267,2278 ---- } lsp->ls_kstat->ks_lock = &lsp->ls_kstat_lock; kstat_zone_add(lsp->ls_kstat, GLOBAL_ZONEID); + lsp->ls_readonly = klip->li_readonly; + if ((error = lofi_init_crypto(lsp, klip)) != 0) goto err; if ((error = lofi_init_compress(lsp)) != 0) goto err;
*** 2341,2351 **** if (err != 0) return (err); mutex_enter(&lofi_lock); if (byfilename) { ! if ((err = file_to_lofi(klip->li_filename, &lsp)) != 0) { mutex_exit(&lofi_lock); return (err); } } else if (klip->li_minor == 0) { mutex_exit(&lofi_lock); --- 2369,2380 ---- if (err != 0) return (err); mutex_enter(&lofi_lock); if (byfilename) { ! if ((err = file_to_lofi(klip->li_filename, klip->li_readonly, ! &lsp)) != 0) { mutex_exit(&lofi_lock); return (err); } } else if (klip->li_minor == 0) { mutex_exit(&lofi_lock);
*** 2458,2477 **** sizeof (klip->li_filename), CRED()) != 0) { (void) strlcpy(klip->li_filename, "?", sizeof (klip->li_filename)); } (void) strlcpy(klip->li_algorithm, lsp->ls_comp_algorithm, sizeof (klip->li_algorithm)); klip->li_crypto_enabled = lsp->ls_crypto_enabled; mutex_exit(&lofi_lock); error = copy_out_lofi_ioctl(klip, ulip, ioctl_flag); free_lofi_ioctl(klip); return (error); case LOFI_GET_MINOR: mutex_enter(&lofi_lock); ! error = file_to_lofi(klip->li_filename, &lsp); if (error == 0) klip->li_minor = getminor(lsp->ls_dev); mutex_exit(&lofi_lock); if (error == 0) --- 2487,2509 ---- sizeof (klip->li_filename), CRED()) != 0) { (void) strlcpy(klip->li_filename, "?", sizeof (klip->li_filename)); } + klip->li_readonly = lsp->ls_readonly; + (void) strlcpy(klip->li_algorithm, lsp->ls_comp_algorithm, sizeof (klip->li_algorithm)); klip->li_crypto_enabled = lsp->ls_crypto_enabled; mutex_exit(&lofi_lock); error = copy_out_lofi_ioctl(klip, ulip, ioctl_flag); free_lofi_ioctl(klip); return (error); case LOFI_GET_MINOR: mutex_enter(&lofi_lock); ! error = file_to_lofi(klip->li_filename, ! klip->li_readonly, &lsp); if (error == 0) klip->li_minor = getminor(lsp->ls_dev); mutex_exit(&lofi_lock); if (error == 0)
*** 2479,2489 **** free_lofi_ioctl(klip); return (error); case LOFI_CHECK_COMPRESSED: mutex_enter(&lofi_lock); ! error = file_to_lofi(klip->li_filename, &lsp); if (error != 0) { mutex_exit(&lofi_lock); free_lofi_ioctl(klip); return (error); } --- 2511,2522 ---- free_lofi_ioctl(klip); return (error); case LOFI_CHECK_COMPRESSED: mutex_enter(&lofi_lock); ! error = file_to_lofi(klip->li_filename, ! klip->li_readonly, &lsp); if (error != 0) { mutex_exit(&lofi_lock); free_lofi_ioctl(klip); return (error); }