version 1.15, 2007/07/10 09:50:09 |
version 1.15.14.3, 2008/02/18 21:07:32 |
|
|
*/ |
*/ |
|
|
#include <sys/cdefs.h> |
#include <sys/cdefs.h> |
__RCSID("$NetBSD$"); |
__KERNEL_RCSID(0, "$NetBSD$"); |
|
|
#include "opt_ffs.h" |
#include "opt_ffs.h" |
|
|
|
|
ufs_extattr_uepm_lock(struct ufsmount *ump) |
ufs_extattr_uepm_lock(struct ufsmount *ump) |
{ |
{ |
|
|
/* Ideally, LK_CANRECURSE would not be used, here. */ |
/* XXX Why does this need to be recursive? */ |
lockmgr(&ump->um_extattr.uepm_lock, LK_EXCLUSIVE | |
if (mutex_owned(&ump->um_extattr.uepm_lock)) { |
LK_CANRECURSE, NULL); |
ump->um_extattr.uepm_lockcnt++; |
|
return; |
|
} |
|
mutex_enter(&ump->um_extattr.uepm_lock); |
} |
} |
|
|
static void |
static void |
ufs_extattr_uepm_unlock(struct ufsmount *ump) |
ufs_extattr_uepm_unlock(struct ufsmount *ump) |
{ |
{ |
|
|
lockmgr(&ump->um_extattr.uepm_lock, LK_RELEASE, NULL); |
if (ump->um_extattr.uepm_lockcnt != 0) { |
|
KASSERT(mutex_owned(&ump->um_extattr.uepm_lock)); |
|
ump->um_extattr.uepm_lockcnt--; |
|
} |
|
mutex_exit(&ump->um_extattr.uepm_lock); |
} |
} |
|
|
/*- |
/*- |
Line 170 ufs_extattr_uepm_init(struct ufs_extattr |
|
Line 177 ufs_extattr_uepm_init(struct ufs_extattr |
|
{ |
{ |
|
|
uepm->uepm_flags = 0; |
uepm->uepm_flags = 0; |
|
uepm->uepm_lockcnt = 0; |
|
|
LIST_INIT(&uepm->uepm_list); |
LIST_INIT(&uepm->uepm_list); |
/* XXX is PVFS right, here? */ |
mutex_init(&uepm->uepm_lock, MUTEX_DEFAULT, IPL_NONE); |
lockinit(&uepm->uepm_lock, PVFS, "ufsea", 0, 0); |
|
uepm->uepm_flags |= UFS_EXTATTR_UEPM_INITIALIZED; |
uepm->uepm_flags |= UFS_EXTATTR_UEPM_INITIALIZED; |
} |
} |
|
|
Line 197 ufs_extattr_uepm_destroy(struct ufs_exta |
|
Line 204 ufs_extattr_uepm_destroy(struct ufs_exta |
|
* during unmount, and with vfs_busy(). |
* during unmount, and with vfs_busy(). |
*/ |
*/ |
uepm->uepm_flags &= ~UFS_EXTATTR_UEPM_INITIALIZED; |
uepm->uepm_flags &= ~UFS_EXTATTR_UEPM_INITIALIZED; |
lockmgr(&uepm->uepm_lock, LK_DRAIN, NULL); |
mutex_destroy(&uepm->uepm_lock); |
} |
} |
|
|
/* |
/* |
Line 305 ufs_extattr_enable_with_open(struct ufsm |
|
Line 312 ufs_extattr_enable_with_open(struct ufsm |
|
{ |
{ |
int error; |
int error; |
|
|
error = VOP_OPEN(vp, FREAD|FWRITE, l->l_cred, l); |
error = VOP_OPEN(vp, FREAD|FWRITE, l->l_cred); |
if (error) { |
if (error) { |
printf("ufs_extattr_enable_with_open.VOP_OPEN(): failed " |
printf("ufs_extattr_enable_with_open.VOP_OPEN(): failed " |
"with %d\n", error); |
"with %d\n", error); |
Line 313 ufs_extattr_enable_with_open(struct ufsm |
|
Line 320 ufs_extattr_enable_with_open(struct ufsm |
|
return (error); |
return (error); |
} |
} |
|
|
|
mutex_enter(&vp->v_interlock); |
vp->v_writecount++; |
vp->v_writecount++; |
|
mutex_exit(&vp->v_interlock); |
|
|
vref(vp); |
vref(vp); |
|
|
Line 528 ufs_extattr_autostart(struct mount *mp, |
|
Line 537 ufs_extattr_autostart(struct mount *mp, |
|
/* |
/* |
* Stop extended attribute support on an FS. |
* Stop extended attribute support on an FS. |
*/ |
*/ |
int |
void |
ufs_extattr_stop(struct mount *mp, struct lwp *l) |
ufs_extattr_stop(struct mount *mp, struct lwp *l) |
{ |
{ |
struct ufs_extattr_list_entry *uele; |
struct ufs_extattr_list_entry *uele; |
struct ufsmount *ump = VFSTOUFS(mp); |
struct ufsmount *ump = VFSTOUFS(mp); |
int error = 0; |
|
|
|
ufs_extattr_uepm_lock(ump); |
ufs_extattr_uepm_lock(ump); |
|
|
Line 542 ufs_extattr_stop(struct mount *mp, struc |
|
Line 550 ufs_extattr_stop(struct mount *mp, struc |
|
* the processing work. |
* the processing work. |
*/ |
*/ |
if (!(ump->um_extattr.uepm_flags & UFS_EXTATTR_UEPM_STARTED)) { |
if (!(ump->um_extattr.uepm_flags & UFS_EXTATTR_UEPM_STARTED)) { |
error = EOPNOTSUPP; |
|
goto unlock; |
goto unlock; |
} |
} |
|
|
Line 559 ufs_extattr_stop(struct mount *mp, struc |
|
Line 566 ufs_extattr_stop(struct mount *mp, struc |
|
|
|
unlock: |
unlock: |
ufs_extattr_uepm_unlock(ump); |
ufs_extattr_uepm_unlock(ump); |
|
|
return (error); |
|
} |
} |
|
|
/* |
/* |
Line 611 ufs_extattr_enable(struct ufsmount *ump, |
|
Line 616 ufs_extattr_enable(struct ufsmount *ump, |
|
auio.uio_rw = UIO_READ; |
auio.uio_rw = UIO_READ; |
UIO_SETUP_SYSSPACE(&auio); |
UIO_SETUP_SYSSPACE(&auio); |
|
|
VOP_LEASE(backing_vnode, l, l->l_cred, LEASE_WRITE); |
|
vn_lock(backing_vnode, LK_SHARED | LK_RETRY); |
vn_lock(backing_vnode, LK_SHARED | LK_RETRY); |
error = VOP_READ(backing_vnode, &auio, IO_NODELOCKED, |
error = VOP_READ(backing_vnode, &auio, IO_NODELOCKED, |
ump->um_extattr.uepm_ucred); |
ump->um_extattr.uepm_ucred); |
Line 702 ufs_extattr_disable(struct ufsmount *ump |
|
Line 706 ufs_extattr_disable(struct ufsmount *ump |
|
*/ |
*/ |
int |
int |
ufs_extattrctl(struct mount *mp, int cmd, struct vnode *filename_vp, |
ufs_extattrctl(struct mount *mp, int cmd, struct vnode *filename_vp, |
int attrnamespace, const char *attrname, struct lwp *l) |
int attrnamespace, const char *attrname) |
{ |
{ |
|
struct lwp *l = curlwp; |
struct ufsmount *ump = VFSTOUFS(mp); |
struct ufsmount *ump = VFSTOUFS(mp); |
int error; |
int error; |
|
|
Line 737 ufs_extattrctl(struct mount *mp, int cmd |
|
Line 742 ufs_extattrctl(struct mount *mp, int cmd |
|
if (attrname != NULL) |
if (attrname != NULL) |
return (EINVAL); |
return (EINVAL); |
|
|
error = ufs_extattr_stop(mp, l); |
ufs_extattr_stop(mp, l); |
return (error); |
return (0); |
|
|
case UFS_EXTATTR_CMD_ENABLE: |
case UFS_EXTATTR_CMD_ENABLE: |
if (filename_vp == NULL) |
if (filename_vp == NULL) |
Line 789 vop_getextattr { |
|
Line 794 vop_getextattr { |
|
INOUT struct uio *a_uio; |
INOUT struct uio *a_uio; |
OUT size_t *a_size; |
OUT size_t *a_size; |
IN kauth_cred_t a_cred; |
IN kauth_cred_t a_cred; |
IN struct lwp *a_l; |
|
}; |
}; |
*/ |
*/ |
{ |
{ |
Line 800 vop_getextattr { |
|
Line 804 vop_getextattr { |
|
ufs_extattr_uepm_lock(ump); |
ufs_extattr_uepm_lock(ump); |
|
|
error = ufs_extattr_get(ap->a_vp, ap->a_attrnamespace, ap->a_name, |
error = ufs_extattr_get(ap->a_vp, ap->a_attrnamespace, ap->a_name, |
ap->a_uio, ap->a_size, ap->a_cred, ap->a_l); |
ap->a_uio, ap->a_size, ap->a_cred, curlwp); |
|
|
ufs_extattr_uepm_unlock(ump); |
ufs_extattr_uepm_unlock(ump); |
|
|
Line 871 ufs_extattr_get(struct vnode *vp, int at |
|
Line 875 ufs_extattr_get(struct vnode *vp, int at |
|
UIO_SETUP_SYSSPACE(&local_aio); |
UIO_SETUP_SYSSPACE(&local_aio); |
|
|
/* |
/* |
* Acquire locks. |
|
*/ |
|
VOP_LEASE(attribute->uele_backing_vnode, l, cred, LEASE_READ); |
|
/* |
|
* Don't need to get a lock on the backing file if the getattr is |
* Don't need to get a lock on the backing file if the getattr is |
* being applied to the backing file, as the lock is already held. |
* being applied to the backing file, as the lock is already held. |
*/ |
*/ |
Line 970 vop_deleteextattr { |
|
Line 970 vop_deleteextattr { |
|
IN int a_attrnamespace; |
IN int a_attrnamespace; |
IN const char *a_name; |
IN const char *a_name; |
IN kauth_cred_t a_cred; |
IN kauth_cred_t a_cred; |
IN struct lwp *a_l; |
|
}; |
}; |
*/ |
*/ |
{ |
{ |
Line 981 vop_deleteextattr { |
|
Line 980 vop_deleteextattr { |
|
ufs_extattr_uepm_lock(ump); |
ufs_extattr_uepm_lock(ump); |
|
|
error = ufs_extattr_rm(ap->a_vp, ap->a_attrnamespace, ap->a_name, |
error = ufs_extattr_rm(ap->a_vp, ap->a_attrnamespace, ap->a_name, |
ap->a_cred, ap->a_l); |
ap->a_cred, curlwp); |
|
|
ufs_extattr_uepm_unlock(ump); |
ufs_extattr_uepm_unlock(ump); |
|
|
Line 1000 vop_setextattr { |
|
Line 999 vop_setextattr { |
|
IN const char *a_name; |
IN const char *a_name; |
INOUT struct uio *a_uio; |
INOUT struct uio *a_uio; |
IN kauth_cred_t a_cred; |
IN kauth_cred_t a_cred; |
IN struct lwp *a_l; |
|
}; |
}; |
*/ |
*/ |
{ |
{ |
Line 1013 vop_setextattr { |
|
Line 1011 vop_setextattr { |
|
/* |
/* |
* XXX: No longer a supported way to delete extended attributes. |
* XXX: No longer a supported way to delete extended attributes. |
*/ |
*/ |
if (ap->a_uio == NULL) |
if (ap->a_uio == NULL) { |
|
ufs_extattr_uepm_unlock(ump); |
return (EINVAL); |
return (EINVAL); |
|
} |
|
|
error = ufs_extattr_set(ap->a_vp, ap->a_attrnamespace, ap->a_name, |
error = ufs_extattr_set(ap->a_vp, ap->a_attrnamespace, ap->a_name, |
ap->a_uio, ap->a_cred, ap->a_l); |
ap->a_uio, ap->a_cred, curlwp); |
|
|
ufs_extattr_uepm_unlock(ump); |
ufs_extattr_uepm_unlock(ump); |
|
|
Line 1092 ufs_extattr_set(struct vnode *vp, int at |
|
Line 1092 ufs_extattr_set(struct vnode *vp, int at |
|
UIO_SETUP_SYSSPACE(&local_aio); |
UIO_SETUP_SYSSPACE(&local_aio); |
|
|
/* |
/* |
* Acquire locks. |
|
*/ |
|
VOP_LEASE(attribute->uele_backing_vnode, l, cred, LEASE_WRITE); |
|
|
|
/* |
|
* Don't need to get a lock on the backing file if the setattr is |
* Don't need to get a lock on the backing file if the setattr is |
* being applied to the backing file, as the lock is already held. |
* being applied to the backing file, as the lock is already held. |
*/ |
*/ |
Line 1193 ufs_extattr_rm(struct vnode *vp, int att |
|
Line 1188 ufs_extattr_rm(struct vnode *vp, int att |
|
local_aio.uio_resid = sizeof(struct ufs_extattr_header); |
local_aio.uio_resid = sizeof(struct ufs_extattr_header); |
UIO_SETUP_SYSSPACE(&local_aio); |
UIO_SETUP_SYSSPACE(&local_aio); |
|
|
VOP_LEASE(attribute->uele_backing_vnode, l, cred, LEASE_WRITE); |
|
|
|
/* |
/* |
* Don't need to get the lock on the backing vnode if the vnode we're |
* Don't need to get the lock on the backing vnode if the vnode we're |
* modifying is it, as we already hold the lock. |
* modifying is it, as we already hold the lock. |