version 1.21.4.2, 2006/06/21 15:09:36 |
version 1.21.4.3, 2006/12/30 20:50:01 |
Line 116 tmpfs_alloc_node(struct tmpfs_mount *tmp |
|
Line 116 tmpfs_alloc_node(struct tmpfs_mount *tmp |
|
if (nnode == NULL) |
if (nnode == NULL) |
return ENOSPC; |
return ENOSPC; |
nnode->tn_id = tmp->tm_nodes_last++; |
nnode->tn_id = tmp->tm_nodes_last++; |
nnode->tn_gen = 0; |
nnode->tn_gen = arc4random(); |
} else { |
} else { |
nnode = LIST_FIRST(&tmp->tm_nodes_avail); |
nnode = LIST_FIRST(&tmp->tm_nodes_avail); |
LIST_REMOVE(nnode, tn_entries); |
LIST_REMOVE(nnode, tn_entries); |
Line 155 tmpfs_alloc_node(struct tmpfs_mount *tmp |
|
Line 155 tmpfs_alloc_node(struct tmpfs_mount *tmp |
|
nnode->tn_spec.tn_dir.tn_readdir_lastp = NULL; |
nnode->tn_spec.tn_dir.tn_readdir_lastp = NULL; |
nnode->tn_links++; |
nnode->tn_links++; |
nnode->tn_spec.tn_dir.tn_parent->tn_links++; |
nnode->tn_spec.tn_dir.tn_parent->tn_links++; |
|
if (parent != NULL) { |
|
KASSERT(parent->tn_vnode != NULL); |
|
VN_KNOTE(parent->tn_vnode, NOTE_LINK); |
|
} |
break; |
break; |
|
|
case VFIFO: |
case VFIFO: |
Line 270 tmpfs_free_node(struct tmpfs_mount *tmp, |
|
Line 274 tmpfs_free_node(struct tmpfs_mount *tmp, |
|
* The new directory entry is returned in *de. |
* The new directory entry is returned in *de. |
* |
* |
* The link count of node is increased by one to reflect the new object |
* The link count of node is increased by one to reflect the new object |
* referencing it. |
* referencing it. This takes care of notifying kqueue listeners about |
|
* this change. |
* |
* |
* Returns zero on success or an appropriate error code on failure. |
* Returns zero on success or an appropriate error code on failure. |
*/ |
*/ |
Line 294 tmpfs_alloc_dirent(struct tmpfs_mount *t |
|
Line 299 tmpfs_alloc_dirent(struct tmpfs_mount *t |
|
nde->td_node = node; |
nde->td_node = node; |
|
|
node->tn_links++; |
node->tn_links++; |
|
if (node->tn_links > 1 && node->tn_vnode != NULL) |
|
VN_KNOTE(node->tn_vnode, NOTE_LINK); |
*de = nde; |
*de = nde; |
|
|
return 0; |
return 0; |
Line 309 tmpfs_alloc_dirent(struct tmpfs_mount *t |
|
Line 316 tmpfs_alloc_dirent(struct tmpfs_mount *t |
|
* object that referenced it. This only happens if 'node_exists' is true; |
* object that referenced it. This only happens if 'node_exists' is true; |
* otherwise the function will not access the node referred to by the |
* otherwise the function will not access the node referred to by the |
* directory entry, as it may already have been released from the outside. |
* directory entry, as it may already have been released from the outside. |
|
* |
|
* Interested parties (kqueue) are notified of the link count change; note |
|
* that this can include both the node pointed to by the directory entry |
|
* as well as its parent. |
*/ |
*/ |
void |
void |
tmpfs_free_dirent(struct tmpfs_mount *tmp, struct tmpfs_dirent *de, |
tmpfs_free_dirent(struct tmpfs_mount *tmp, struct tmpfs_dirent *de, |
Line 321 tmpfs_free_dirent(struct tmpfs_mount *tm |
|
Line 332 tmpfs_free_dirent(struct tmpfs_mount *tm |
|
|
|
KASSERT(node->tn_links > 0); |
KASSERT(node->tn_links > 0); |
node->tn_links--; |
node->tn_links--; |
|
if (node->tn_vnode != NULL) |
|
VN_KNOTE(node->tn_vnode, node->tn_links == 0 ? |
|
NOTE_DELETE : NOTE_LINK); |
|
if (node->tn_type == VDIR) |
|
VN_KNOTE(node->tn_spec.tn_dir.tn_parent->tn_vnode, |
|
NOTE_LINK); |
} |
} |
|
|
tmpfs_str_pool_put(&tmp->tm_str_pool, de->td_name, de->td_namelen); |
tmpfs_str_pool_put(&tmp->tm_str_pool, de->td_name, de->td_namelen); |
Line 522 tmpfs_alloc_file(struct vnode *dvp, stru |
|
Line 539 tmpfs_alloc_file(struct vnode *dvp, stru |
|
* insert the new node into the directory, an operation that |
* insert the new node into the directory, an operation that |
* cannot fail. */ |
* cannot fail. */ |
tmpfs_dir_attach(dvp, de); |
tmpfs_dir_attach(dvp, de); |
VN_KNOTE(dvp, NOTE_WRITE); |
|
|
|
out: |
out: |
if (error != 0 || !(cnp->cn_flags & SAVESTART)) |
if (error != 0 || !(cnp->cn_flags & SAVESTART)) |
|
|
* Attaches the directory entry de to the directory represented by vp. |
* Attaches the directory entry de to the directory represented by vp. |
* Note that this does not change the link count of the node pointed by |
* Note that this does not change the link count of the node pointed by |
* the directory entry, as this is done by tmpfs_alloc_dirent. |
* the directory entry, as this is done by tmpfs_alloc_dirent. |
|
* |
|
* As the "parent" directory changes, interested parties are notified of |
|
* a write to it. |
*/ |
*/ |
void |
void |
tmpfs_dir_attach(struct vnode *vp, struct tmpfs_dirent *de) |
tmpfs_dir_attach(struct vnode *vp, struct tmpfs_dirent *de) |
Line 554 tmpfs_dir_attach(struct vnode *vp, struc |
|
Line 573 tmpfs_dir_attach(struct vnode *vp, struc |
|
dnode->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED | \ |
dnode->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED | \ |
TMPFS_NODE_MODIFIED; |
TMPFS_NODE_MODIFIED; |
uvm_vnp_setsize(vp, dnode->tn_size); |
uvm_vnp_setsize(vp, dnode->tn_size); |
|
|
|
VN_KNOTE(vp, NOTE_WRITE); |
} |
} |
|
|
/* --------------------------------------------------------------------- */ |
/* --------------------------------------------------------------------- */ |
Line 562 tmpfs_dir_attach(struct vnode *vp, struc |
|
Line 583 tmpfs_dir_attach(struct vnode *vp, struc |
|
* Detaches the directory entry de from the directory represented by vp. |
* Detaches the directory entry de from the directory represented by vp. |
* Note that this does not change the link count of the node pointed by |
* Note that this does not change the link count of the node pointed by |
* the directory entry, as this is done by tmpfs_free_dirent. |
* the directory entry, as this is done by tmpfs_free_dirent. |
|
* |
|
* As the "parent" directory changes, interested parties are notified of |
|
* a write to it. |
*/ |
*/ |
void |
void |
tmpfs_dir_detach(struct vnode *vp, struct tmpfs_dirent *de) |
tmpfs_dir_detach(struct vnode *vp, struct tmpfs_dirent *de) |
Line 582 tmpfs_dir_detach(struct vnode *vp, struc |
|
Line 606 tmpfs_dir_detach(struct vnode *vp, struc |
|
dnode->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED | \ |
dnode->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED | \ |
TMPFS_NODE_MODIFIED; |
TMPFS_NODE_MODIFIED; |
uvm_vnp_setsize(vp, dnode->tn_size); |
uvm_vnp_setsize(vp, dnode->tn_size); |
|
|
|
VN_KNOTE(vp, NOTE_WRITE); |
} |
} |
|
|
/* --------------------------------------------------------------------- */ |
/* --------------------------------------------------------------------- */ |
Line 695 tmpfs_dir_getdotdotdent(struct tmpfs_nod |
|
Line 721 tmpfs_dir_getdotdotdent(struct tmpfs_nod |
|
if (de == NULL) |
if (de == NULL) |
uio->uio_offset = TMPFS_DIRCOOKIE_EOF; |
uio->uio_offset = TMPFS_DIRCOOKIE_EOF; |
else |
else |
uio->uio_offset = TMPFS_DIRCOOKIE(de); |
uio->uio_offset = tmpfs_dircookie(de); |
} |
} |
} |
} |
|
|
Line 720 tmpfs_dir_lookupbycookie(struct tmpfs_no |
|
Line 746 tmpfs_dir_lookupbycookie(struct tmpfs_no |
|
} |
} |
|
|
TAILQ_FOREACH(de, &node->tn_spec.tn_dir.tn_dir, td_entries) { |
TAILQ_FOREACH(de, &node->tn_spec.tn_dir.tn_dir, td_entries) { |
if (TMPFS_DIRCOOKIE(de) == cookie) { |
if (tmpfs_dircookie(de) == cookie) { |
break; |
break; |
} |
} |
} |
} |
Line 829 tmpfs_dir_getdents(struct tmpfs_node *no |
|
Line 855 tmpfs_dir_getdents(struct tmpfs_node *no |
|
node->tn_spec.tn_dir.tn_readdir_lastp = NULL; |
node->tn_spec.tn_dir.tn_readdir_lastp = NULL; |
} else { |
} else { |
node->tn_spec.tn_dir.tn_readdir_lastn = uio->uio_offset = |
node->tn_spec.tn_dir.tn_readdir_lastn = uio->uio_offset = |
TMPFS_DIRCOOKIE(de); |
tmpfs_dircookie(de); |
node->tn_spec.tn_dir.tn_readdir_lastp = de; |
node->tn_spec.tn_dir.tn_readdir_lastp = de; |
} |
} |
|
|
Line 845 tmpfs_dir_getdents(struct tmpfs_node *no |
|
Line 871 tmpfs_dir_getdents(struct tmpfs_node *no |
|
* the size newsize. 'vp' must point to a vnode that represents a regular |
* the size newsize. 'vp' must point to a vnode that represents a regular |
* file. 'newsize' must be positive. |
* file. 'newsize' must be positive. |
* |
* |
|
* If the file is extended, the appropriate kevent is raised. This does |
|
* not rise a write event though because resizing is not the same as |
|
* writing. |
|
* |
* Returns zero on success or an appropriate error code on failure. |
* Returns zero on success or an appropriate error code on failure. |
*/ |
*/ |
int |
int |
Line 908 tmpfs_reg_resize(struct vnode *vp, off_t |
|
Line 938 tmpfs_reg_resize(struct vnode *vp, off_t |
|
|
|
error = 0; |
error = 0; |
|
|
|
if (newsize > oldsize) |
|
VN_KNOTE(vp, NOTE_EXTEND); |
|
|
out: |
out: |
return error; |
return error; |
} |
} |
Line 955 tmpfs_mem_info(boolean_t total) |
|
Line 988 tmpfs_mem_info(boolean_t total) |
|
* The vnode must be locked on entry and remain locked on exit. |
* The vnode must be locked on entry and remain locked on exit. |
*/ |
*/ |
int |
int |
tmpfs_chflags(struct vnode *vp, int flags, kauth_cred_t cred, struct proc *p) |
tmpfs_chflags(struct vnode *vp, int flags, kauth_cred_t cred, struct lwp *l) |
{ |
{ |
int error; |
int error; |
struct tmpfs_node *node; |
struct tmpfs_node *node; |
Line 973 tmpfs_chflags(struct vnode *vp, int flag |
|
Line 1006 tmpfs_chflags(struct vnode *vp, int flag |
|
* somewhere? */ |
* somewhere? */ |
if (kauth_cred_geteuid(cred) != node->tn_uid && |
if (kauth_cred_geteuid(cred) != node->tn_uid && |
(error = kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, |
(error = kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, |
&p->p_acflag))) |
&l->l_acflag))) |
return error; |
return error; |
if (kauth_cred_geteuid(cred) == 0) { |
if (kauth_cred_geteuid(cred) == 0) { |
/* The super-user is only allowed to change flags if the file |
/* The super-user is only allowed to change flags if the file |
Line 1011 tmpfs_chflags(struct vnode *vp, int flag |
|
Line 1044 tmpfs_chflags(struct vnode *vp, int flag |
|
* The vnode must be locked on entry and remain locked on exit. |
* The vnode must be locked on entry and remain locked on exit. |
*/ |
*/ |
int |
int |
tmpfs_chmod(struct vnode *vp, mode_t mode, kauth_cred_t cred, struct proc *p) |
tmpfs_chmod(struct vnode *vp, mode_t mode, kauth_cred_t cred, struct lwp *l) |
{ |
{ |
int error, ismember = 0; |
int error, ismember = 0; |
struct tmpfs_node *node; |
struct tmpfs_node *node; |
Line 1033 tmpfs_chmod(struct vnode *vp, mode_t mod |
|
Line 1066 tmpfs_chmod(struct vnode *vp, mode_t mod |
|
* somewhere? */ |
* somewhere? */ |
if (kauth_cred_geteuid(cred) != node->tn_uid && |
if (kauth_cred_geteuid(cred) != node->tn_uid && |
(error = kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, |
(error = kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, |
&p->p_acflag))) |
&l->l_acflag))) |
return error; |
return error; |
if (kauth_cred_geteuid(cred) != 0) { |
if (kauth_cred_geteuid(cred) != 0) { |
if (vp->v_type != VDIR && (mode & S_ISTXT)) |
if (vp->v_type != VDIR && (mode & S_ISTXT)) |
Line 1065 tmpfs_chmod(struct vnode *vp, mode_t mod |
|
Line 1098 tmpfs_chmod(struct vnode *vp, mode_t mod |
|
*/ |
*/ |
int |
int |
tmpfs_chown(struct vnode *vp, uid_t uid, gid_t gid, kauth_cred_t cred, |
tmpfs_chown(struct vnode *vp, uid_t uid, gid_t gid, kauth_cred_t cred, |
struct proc *p) |
struct lwp *l) |
{ |
{ |
int error, ismember = 0; |
int error, ismember = 0; |
struct tmpfs_node *node; |
struct tmpfs_node *node; |
Line 1095 tmpfs_chown(struct vnode *vp, uid_t uid, |
|
Line 1128 tmpfs_chown(struct vnode *vp, uid_t uid, |
|
* somewhere? */ |
* somewhere? */ |
if ((kauth_cred_geteuid(cred) != node->tn_uid || uid != node->tn_uid || |
if ((kauth_cred_geteuid(cred) != node->tn_uid || uid != node->tn_uid || |
(gid != node->tn_gid && !(kauth_cred_getegid(cred) == node->tn_gid || |
(gid != node->tn_gid && !(kauth_cred_getegid(cred) == node->tn_gid || |
(kauth_cred_ismember_gid(cred, gid, &ismember) == 0 && ismember)))) && |
(kauth_cred_ismember_gid(cred, gid, &ismember) == 0 && ismember)))) && |
((error = kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, |
((error = kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, |
&p->p_acflag)) != 0)) |
&l->l_acflag)) != 0)) |
return error; |
return error; |
|
|
node->tn_uid = uid; |
node->tn_uid = uid; |
Line 1120 tmpfs_chown(struct vnode *vp, uid_t uid, |
|
Line 1153 tmpfs_chown(struct vnode *vp, uid_t uid, |
|
*/ |
*/ |
int |
int |
tmpfs_chsize(struct vnode *vp, u_quad_t size, kauth_cred_t cred, |
tmpfs_chsize(struct vnode *vp, u_quad_t size, kauth_cred_t cred, |
struct proc *p) |
struct lwp *l) |
{ |
{ |
int error; |
int error; |
struct tmpfs_node *node; |
struct tmpfs_node *node; |
Line 1199 tmpfs_chtimes(struct vnode *vp, struct t |
|
Line 1232 tmpfs_chtimes(struct vnode *vp, struct t |
|
* somewhere? */ |
* somewhere? */ |
if (kauth_cred_geteuid(cred) != node->tn_uid && |
if (kauth_cred_geteuid(cred) != node->tn_uid && |
(error = kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, |
(error = kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, |
&l->l_proc->p_acflag)) && |
&l->l_acflag)) && ((vaflags & VA_UTIMES_NULL) == 0 || |
((vaflags & VA_UTIMES_NULL) == 0 || |
|
(error = VOP_ACCESS(vp, VWRITE, cred, l)))) |
(error = VOP_ACCESS(vp, VWRITE, cred, l)))) |
return error; |
return error; |
|
|
Line 1211 tmpfs_chtimes(struct vnode *vp, struct t |
|
Line 1243 tmpfs_chtimes(struct vnode *vp, struct t |
|
node->tn_status |= TMPFS_NODE_MODIFIED; |
node->tn_status |= TMPFS_NODE_MODIFIED; |
|
|
tmpfs_update(vp, atime, mtime, 0); |
tmpfs_update(vp, atime, mtime, 0); |
|
VN_KNOTE(vp, NOTE_ATTRIB); |
|
|
KASSERT(VOP_ISLOCKED(vp)); |
KASSERT(VOP_ISLOCKED(vp)); |
|
|
Line 1264 tmpfs_update(struct vnode *vp, const str |
|
Line 1297 tmpfs_update(struct vnode *vp, const str |
|
|
|
node = VP_TO_TMPFS_NODE(vp); |
node = VP_TO_TMPFS_NODE(vp); |
|
|
|
#if 0 |
if (flags & UPDATE_CLOSE) |
if (flags & UPDATE_CLOSE) |
; /* XXX Need to do anything special? */ |
; /* XXX Need to do anything special? */ |
|
#endif |
|
|
tmpfs_itimes(vp, acc, mod); |
tmpfs_itimes(vp, acc, mod); |
|
|
Line 1295 tmpfs_truncate(struct vnode *vp, off_t l |
|
Line 1330 tmpfs_truncate(struct vnode *vp, off_t l |
|
} |
} |
|
|
error = tmpfs_reg_resize(vp, length); |
error = tmpfs_reg_resize(vp, length); |
if (error == 0) { |
if (error == 0) |
VN_KNOTE(vp, NOTE_ATTRIB | (extended ? NOTE_EXTEND : 0)); |
|
node->tn_status |= TMPFS_NODE_CHANGED | TMPFS_NODE_MODIFIED; |
node->tn_status |= TMPFS_NODE_CHANGED | TMPFS_NODE_MODIFIED; |
} |
|
|
|
out: |
out: |
tmpfs_update(vp, NULL, NULL, 0); |
tmpfs_update(vp, NULL, NULL, 0); |