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);
}