⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inode.c

📁 一个简单的操作系统minix的核心代码
💻 C
📖 第 1 页 / 共 2 页
字号:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
				src/fs/inode.c	 	 
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

21500	/* This file manages the inode table.  There are procedures to allocate and
21501	 * deallocate inodes, acquire, erase, and release them, and read and write
21502	 * them from the disk.
21503	 *
21504	 * The entry points into this file are
21505	 *   get_inode:    search inode table for a given inode; if not there, read it
21506	 *   put_inode:    indicate that an inode is no longer needed in memory
21507	 *   alloc_inode:  allocate a new, unused inode
21508	 *   wipe_inode:   erase some fields of a newly allocated inode
21509	 *   free_inode:   mark an inode as available for a new file
21510	 *   update_times: update atime, ctime, and mtime
21511	 *   rw_inode:     read a disk block and extract an inode, or corresp. write
21512	 *   old_icopy:    copy to/from in-core inode struct and disk inode (V1.x)
21513	 *   new_icopy:    copy to/from in-core inode struct and disk inode (V2.x)
21514	 *   dup_inode:    indicate that someone else is using an inode table entry
21515	 */
21516	
21517	#include "fs.h"
21518	#include <minix/boot.h>
21519	#include "buf.h"
21520	#include "file.h"
21521	#include "fproc.h"
21522	#include "inode.h"
21523	#include "super.h"
21524	
21525	FORWARD _PROTOTYPE( void old_icopy, (struct inode *rip, d1_inode *dip,
21526	                                                int direction, int norm));
21527	FORWARD _PROTOTYPE( void new_icopy, (struct inode *rip, d2_inode *dip,
21528	                                                int direction, int norm));
21529	
21530	
21531	/*===========================================================================*
21532	 *                              get_inode                                    *
21533	 *===========================================================================*/
21534	PUBLIC struct inode *get_inode(dev, numb)
21535	dev_t dev;                      /* device on which inode resides */
21536	int numb;                       /* inode number (ANSI: may not be unshort) */
21537	{
21538	/* Find a slot in the inode table, load the specified inode into it, and
21539	 * return a pointer to the slot.  If 'dev' == NO_DEV, just return a free slot.
21540	 */
21541	
21542	  register struct inode *rip, *xp;
21543	
21544	  /* Search the inode table both for (dev, numb) and a free slot. */
21545	  xp = NIL_INODE;
21546	  for (rip = &inode[0]; rip < &inode[NR_INODES]; rip++) {
21547	        if (rip->i_count > 0) { /* only check used slots for (dev, numb) */
21548	                if (rip->i_dev == dev && rip->i_num == numb) {
21549	                        /* This is the inode that we are looking for. */
21550	                        rip->i_count++;
21551	                        return(rip);    /* (dev, numb) found */
21552	                }
21553	        } else {
21554	                xp = rip;       /* remember this free slot for later */
21555	        }
21556	  }
21557	
21558	  /* Inode we want is not currently in use.  Did we find a free slot? */
21559	  if (xp == NIL_INODE) {        /* inode table completely full */
21560	        err_code = ENFILE;
21561	        return(NIL_INODE);
21562	  }
21563	
21564	  /* A free inode slot has been located.  Load the inode into it. */
21565	  xp->i_dev = dev;
21566	  xp->i_num = numb;
21567	  xp->i_count = 1;
21568	  if (dev != NO_DEV) rw_inode(xp, READING);     /* get inode from disk */
21569	  xp->i_update = 0;             /* all the times are initially up-to-date */
21570	
21571	  return(xp);
21572	}
	
	
21575	/*===========================================================================*
21576	 *                              put_inode                                    *
21577	 *===========================================================================*/
21578	PUBLIC void put_inode(rip)
21579	register struct inode *rip;     /* pointer to inode to be released */
21580	{
21581	/* The caller is no longer using this inode.  If no one else is using it either
21582	 * write it back to the disk immediately.  If it has no links, truncate it and
21583	 * return it to the pool of available inodes.
21584	 */
21585	
21586	  if (rip == NIL_INODE) return; /* checking here is easier than in caller */
21587	  if (--rip->i_count == 0) {    /* i_count == 0 means no one is using it now */
21588	        if ((rip->i_nlinks & BYTE) == 0) {
21589	                /* i_nlinks == 0 means free the inode. */
21590	                truncate(rip);  /* return all the disk blocks */
21591	                rip->i_mode = I_NOT_ALLOC;      /* clear I_TYPE field */
21592	                rip->i_dirt = DIRTY;
21593	                free_inode(rip->i_dev, rip->i_num);
21594	        } else {
21595	                if (rip->i_pipe == I_PIPE) truncate(rip);
21596	        }
21597	        rip->i_pipe = NO_PIPE;  /* should always be cleared */
21598	        if (rip->i_dirt == DIRTY) rw_inode(rip, WRITING);
21599	  }
21600	}
	
21602	/*===========================================================================*
21603	 *                              alloc_inode                                  *
21604	 *===========================================================================*/
21605	PUBLIC struct inode *alloc_inode(dev, bits)
21606	dev_t dev;                      /* device on which to allocate the inode */
21607	mode_t bits;                    /* mode of the inode */
21608	{
21609	/* Allocate a free inode on 'dev', and return a pointer to it. */
21610	
21611	  register struct inode *rip;
21612	  register struct super_block *sp;
21613	  int major, minor, inumb;
21614	  bit_t b;
21615	
21616	  sp = get_super(dev);  /* get pointer to super_block */
21617	  if (sp->s_rd_only) {  /* can't allocate an inode on a read only device. */
21618	        err_code = EROFS;
21619	        return(NIL_INODE);
21620	  }
21621	
21622	  /* Acquire an inode from the bit map. */
21623	  b = alloc_bit(sp, IMAP, sp->s_isearch);
21624	  if (b == NO_BIT) {
21625	        err_code = ENFILE;
21626	        major = (int) (sp->s_dev >> MAJOR) & BYTE;
21627	        minor = (int) (sp->s_dev >> MINOR) & BYTE;
21628	        printf("Out of i-nodes on %sdevice %d/%d\n",
21629	                sp->s_dev == ROOT_DEV ? "root " : "", major, minor);
21630	        return(NIL_INODE);
21631	  }
21632	  sp->s_isearch = b;            /* next time start here */
21633	  inumb = (int) b;              /* be careful not to pass unshort as param */
21634	
21635	  /* Try to acquire a slot in the inode table. */
21636	  if ((rip = get_inode(NO_DEV, inumb)) == NIL_INODE) {
21637	        /* No inode table slots available.  Free the inode just allocated. */
21638	        free_bit(sp, IMAP, b);
21639	  } else {
21640	        /* An inode slot is available. Put the inode just allocated into it. */
21641	        rip->i_mode = bits;             /* set up RWX bits */
21642	        rip->i_nlinks = (nlink_t) 0;    /* initial no links */
21643	        rip->i_uid = fp->fp_effuid;     /* file's uid is owner's */
21644	        rip->i_gid = fp->fp_effgid;     /* ditto group id */
21645	        rip->i_dev = dev;               /* mark which device it is on */
21646	        rip->i_ndzones = sp->s_ndzones; /* number of direct zones */
21647	        rip->i_nindirs = sp->s_nindirs; /* number of indirect zones per blk*/
21648	        rip->i_sp = sp;                 /* pointer to super block */
21649	
21650	        /* Fields not cleared already are cleared in wipe_inode().  They have
21651	         * been put there because truncate() needs to clear the same fields if
21652	         * the file happens to be open while being truncated.  It saves space
21653	         * not to repeat the code twice.
21654	         */
21655	        wipe_inode(rip);
21656	  }
21657	
21658	  return(rip);
21659	}
	
21661	/*===========================================================================*
21662	 *                              wipe_inode                                   *
21663	 *===========================================================================*/
21664	PUBLIC void wipe_inode(rip)
21665	register struct inode *rip;     /* the inode to be erased */
21666	{
21667	/* Erase some fields in the inode.  This function is called from alloc_inode()
21668	 * when a new inode is to be allocated, and from truncate(), when an existing
21669	 * inode is to be truncated.
21670	 */
21671	
21672	  register int i;
21673	
21674	  rip->i_size = 0;
21675	  rip->i_update = ATIME | CTIME | MTIME;        /* update all times later */
21676	  rip->i_dirt = DIRTY;
21677	  for (i = 0; i < V2_NR_TZONES; i++) rip->i_zone[i] = NO_ZONE;
21678	}
	
	
21681	/*===========================================================================*
21682	 *                              free_inode                                   *
21683	 *===========================================================================*/
21684	PUBLIC void free_inode(dev, inumb)
21685	dev_t dev;                      /* on which device is the inode */
21686	ino_t inumb;                    /* number of inode to be freed */
21687	{
21688	/* Return an inode to the pool of unallocated inodes. */
21689	
21690	  register struct super_block *sp;
21691	  bit_t b;
21692	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -