Files
Arquivotheca.AIX-4.1.3/bos/kernel/lfs/fee.c
seta75D d6fe8fe829 Init
2021-10-11 22:19:34 -03:00

238 lines
5.8 KiB
C

static char sccsid[] = "@(#)43 1.10.1.8 src/bos/kernel/lfs/fee.c, syslfs, bos411, 9428A410j 6/9/94 07:38:08";
/*
* COMPONENT_NAME: (SYSLFS) Logical File System
*
* FUNCTIONS: fs_fork, fs_exec, fs_exit
*
* ORIGINS: 3, 27
*
* This module contains IBM CONFIDENTIAL code. -- (IBM
* Confidential Restricted when combined with the aggregated
* modules for this product)
* SOURCE MATERIALS
* (C) COPYRIGHT International Business Machines Corp. 1985, 1993
* All Rights Reserved
*
* US Government Users Restricted Rights - Use, duplication or
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
*
*/
#include "sys/user.h"
#include "sys/errno.h"
#include "sys/fs_locks.h"
#include "sys/file.h"
#include "sys/lockf.h"
#include "sys/syspest.h"
#include "sys/proc.h"
#include "sys/fs_hooks.h"
#include "sys/lock_alloc.h"
#include "sys/lockname.h"
#include "sys/sleep.h"
/*
* This file contains routines that are used by the fork, exec, and
* exit system calls to perform file system specific functions.
*/
/*
* fsfork - Perform file system specific tasks resulting from the
* fork system call. This amounts to bumping the reference count
* for each open file and current and root directories.
*/
void
fs_fork(struct user *uchild)
{
int n, maxo;
struct file *fp;
register int klock_rc;
int tlock; /* is multi-thread locking required? */
klock_rc = FS_KLOCK(&kernel_lock, LOCK_SHORT);
/* Do the initialization of the child process u-block. */
/* Initialize the file system locks. */
lock_alloc(&uchild->U_fd_lock,LOCK_ALLOC_PAGED,U_FD_CLASS,
uchild->U_procp-(struct proc *)&proc);
simple_lock_init(&uchild->U_fd_lock);
lock_alloc(&uchild->U_fso_lock,LOCK_ALLOC_PAGED,U_FSO_CLASS,
uchild->U_procp-(struct proc *)&proc);
simple_lock_init(&uchild->U_fso_lock);
/* Initialize the file system event anchor. */
uchild->U_fdevent = EVENT_NULL;
/* Initialize the indicator that file locks have been taken. */
uchild->U_lockflag = 0;
/*
* Walk parent's file descriptor table for open files known to
* parent & increment the global file table reference count for
* each file. Copy the current state of the file descriptors
* to the child's file descriptor table.
* Increment use counts for any open file which has been mapped
* for fshmat.
*/
/* We have to have the U_FD_LOCK in the parent ublock in order
* to get a consistent view of the file descriptor table, and
* of individual descriptors.
*/
if (tlock = (U.U_procp->p_active > 1))
U_FD_LOCK();
maxo = uchild->U_maxofile = U.U_maxofile;
for (n=0; n < maxo; n++)
{
if (((fp = U.U_ufd[n].fp) != NULL) &&
(!(U.U_ufd[n].flags & UF_CLOSING)))
{
/* increment the use count on the file pointer */
fp_hold(fp);
if (U.U_ufd[n].flags & UF_FSHMAT)
fmapfork(n);
/* copy the file descriptor to the child ublock */
uchild->U_ufd[n].fp = U.U_ufd[n].fp;
uchild->U_ufd[n].flags = U.U_ufd[n].flags;
uchild->U_ufd[n].count = 0;
}
else
{
/* remove all unwanted state in the child table */
uchild->U_ufd[n].fp = NULL;
uchild->U_ufd[n].flags = 0;
uchild->U_ufd[n].count = 0;
}
}
if (tlock)
U_FD_UNLOCK();
/*
* Increment the reference counts for the current directory
* and the root directory.
*/
VNOP_HOLD(uchild->U_cdir);
if (uchild->U_rdir)
VNOP_HOLD(uchild->U_rdir);
if (klock_rc != LOCK_NEST)
FS_KUNLOCK(&kernel_lock);
}
/*
* NAME: fs_exec
*
* FUNCTION: Perform file system specific processing associated with
* the exec system call. This consists of closing all files currently
* marked as close on exec. Additionally, audit read and write flags
* to keep read and write state are turned off if on.
*
* NOTES:
* unmap of normal mapped files is done in shmexec
* unmap of fshmat mapped files is initiated here
*/
void
fs_exec()
{
register int klock_rc;
register int i;
int error; /* saved u_error value */
struct file * fp;
struct fs_hook *fs_exech;
klock_rc = FS_KLOCK(&kernel_lock, LOCK_SHORT);
error = u.u_error;
/* NOTE:
* We don't need to take the U_FD_LOCK since we are guaranteed
* to be single-threaded at this point.
*/
for (i=0; i < U.U_maxofile; i++)
{
/*
* Turn off audit state flags
*/
U.U_ufd[i].flags &= ~(UF_AUD_READ|UF_AUD_WRITE);
/*
* Call all registered fs_exec hooks
*/
if ((fp = U.U_ufd[i].fp) != NULL)
for (fs_exech = fs_exech_anchor;
fs_exech;
fs_exech = fs_exech->next)
(fs_exech->hook)(i, fp);
/*
* Call the common code for closing a file descriptor
* if it's marked close on exec.
*/
if ((U.U_ufd[i].flags & FD_CLOEXEC)
&& ((fp = U.U_ufd[i].fp) != NULL))
closefd(i, 1);
if ((U.U_ufd[i].fp != NULL) &&
(U.U_ufd[i].flags & UF_FSHMAT))
rmfmap(i);
}
u.u_error = error;
if (klock_rc != LOCK_NEST)
FS_KUNLOCK(&kernel_lock);
}
/*
* NAME: fs_exit
*
* FUNCTION: Perform file system specific processing associated with
* the exit system call. This consists of closing all open files &
* releasing the process's current and root directory
*/
void
fs_exit()
{
struct file *fp;
register int i;
register int klock_rc;
klock_rc = FS_KLOCK(&kernel_lock, LOCK_SHORT);
/* NOTE:
* We don't need to take the U_FD_LOCK since we are guaranteed
* to be single-threaded at this point.
*/
/* Close all open files */
for (i = 0; i < U.U_maxofile; i++)
if ( (fp = U.U_ufd[i].fp) != NULL )
{
assert(U.U_ufd[i].count == 0);
closefd(i, 0);
}
/*
* Free both the file descriptor lock and the fso lock
* when the process is exiting.
*/
lock_free(&U.U_fd_lock);
lock_free(&U.U_fso_lock);
/* release current directory, if any; kprocs may not have one */
if (U.U_cdir)
VNOP_RELE(U.U_cdir);
/* release root directory, if any */
if (U.U_rdir)
VNOP_RELE(U.U_rdir);
if (klock_rc != LOCK_NEST)
FS_KUNLOCK(&kernel_lock);
}