Exemple #1
0
int FreeBlk(int dev, int blk)

{
    char buf[BLKSIZE * 2];
    struct SupBlock* sptr= (struct SupBlock*) buf;

    readSuper(dev,sptr);

    sptr->sb_nfreeblk++;

    //if list is already full
    if (sptr->sb_freeblkindex==1)
    {
        //then copy (empty) the list into given blk and store its address at index 0 in the list
        WriteBlock(dev,DATA_BLK_STARTS_AT+blk,(char*)sptr->sb_freeblks);
        sptr->sb_freeblks[0]=blk;
        sptr->sb_freeblkindex= BLKSIZE/sizeof(short);
        writeSuper(dev,sptr);

        return 0;//success
    }
    else {
        sptr->sb_freeblkindex--;
        sptr->sb_freeblks[sptr->sb_freeblkindex]=blk;
        writeSuper(dev,sptr);

    }

    return 0;//success

}
Exemple #2
0
int AllocBlk(int dev)
{
    char buf[BLKSIZE * 2];
    struct SupBlock* sptr= (struct SupBlock*) buf;
    readSuper(dev,buf);

    if (sptr->sb_nfreeblk==0) {
        //no free blks available
        return -1;
    }
    sptr->sb_nfreeblk--;
    if (sptr->sb_freeblkindex==BLKSIZE/sizeof(short))//if it is the last entry
     {
        // this will be executed if super-blk free-blk-list becoms empty..now copy the whole block pointed by pointer in list
        // at index 0 to the super-blk free-blk list
        int blkno=sptr->sb_freeblks[0];
        ReadBlock(dev,DATA_BLK_STARTS_AT+blkno,sptr->sb_freeblks);
        //update superblk and freeze the changes
        sptr->sb_freeblkindex=1;
        writeSuper(dev,sptr);
        //now return this block as free block
         return blkno;

    }

    int freeblk=sptr->sb_freeblks[sptr->sb_freeblkindex];
    sptr->sb_freeblkindex++;
    // Freeze the changes in super-block
    writeSuper(dev,sptr);
    return freeblk;



}
Exemple #3
0
int AllocInode(int dev)
{
    char buf[BLKSIZE * 2];

    struct SupBlock* sptr= (struct SupBlock*) buf;
    readSuper(dev,sptr);

    if (sptr->sb_nfreeino==0) {
        //no free inos available
        return -1;
    }
    sptr->sb_nfreeino--;

    if (sptr->sb_freeinoindex==(BLKSIZE-54)/sizeof(short))//if list becomes empty
    {
        // then scan the inode block to search free inodes and fill again the list in superblk
        int i;
        char buff[BLKSIZE];
        int done=0;
        for (i=0; i< 8 && done==0 ; i++)
        {
            ReadBlock(dev,INODE_BLK_STARTS_AT+i,buff);
            struct INode* iptr=(struct INode*) buff;
            int j;
            for (j=0; j< BLKSIZE/sizeof(struct INode) && done==0 ; j++,iptr++)
            {
                if (iptr->i_lnk ==0) // no of hardlinks==0
                {
                    int ino_of_this_inode = i* (BLKSIZE/sizeof(struct INode)) + j + 1;

                    sptr->sb_freeinoindex--;
                    sptr->sb_freeinos[sptr->sb_freeinoindex]=ino_of_this_inode;

                    // if list is full now
                    if (sptr->sb_freeinoindex==0)
                        done=1;
                }
            }
        }
    }


    int free_inode= sptr->sb_freeinos[sptr->sb_freeinoindex];

    // Freeze the changes in super block
    sptr->sb_freeinoindex++;
    writeSuper(dev,buf);

    return free_inode;

}
/*
 *	updateSuper()
 *
 * update synchronously superblock if it is mounted read-write.
 */
int updateSuper(struct super_block *sb, uint state)
{
	struct jfs_superblock *j_sb;
	struct jfs_sb_info *sbi = JFS_SBI(sb);
	struct buffer_head *bh;
	int rc;

	if (sbi->flag & JFS_NOINTEGRITY) {
		if (state == FM_DIRTY) {
			sbi->p_state = state;
			return 0;
		} else if (state == FM_MOUNT) {
			sbi->p_state = sbi->state;
			state = FM_DIRTY;
		} else if (state == FM_CLEAN) {
			state = sbi->p_state;
		} else
			jfs_err("updateSuper: bad state");
	} else if (sbi->state == FM_DIRTY)
		return 0;
	
	if ((rc = readSuper(sb, &bh)))
		return rc;

	j_sb = (struct jfs_superblock *)bh->b_data;

	j_sb->s_state = cpu_to_le32(state);
	sbi->state = state;

	if (state == FM_MOUNT) {
		/* record log's dev_t and mount serial number */
		j_sb->s_logdev = cpu_to_le32(sbi->log->bdev->bd_dev);
		j_sb->s_logserial = cpu_to_le32(sbi->log->serial);
	} else if (state == FM_CLEAN) {
		/*
		 * If this volume is shared with OS/2, OS/2 will need to
		 * recalculate DASD usage, since we don't deal with it.
		 */
		if (j_sb->s_flag & cpu_to_le32(JFS_DASD_ENABLED))
			j_sb->s_flag |= cpu_to_le32(JFS_DASD_PRIME);
	}

	mark_buffer_dirty(bh);
	ll_rw_block(WRITE, 1, &bh);
	wait_on_buffer(bh);
	brelse(bh);

	return 0;
}
Exemple #5
0
int updateSuper(struct super_block *sb, uint state)
{
	struct jfs_superblock *j_sb;
	struct jfs_sb_info *sbi = JFS_SBI(sb);
	struct buffer_head *bh;
	int rc;

	if (sbi->flag & JFS_NOINTEGRITY) {
		if (state == FM_DIRTY) {
			sbi->p_state = state;
			return 0;
		} else if (state == FM_MOUNT) {
			sbi->p_state = sbi->state;
			state = FM_DIRTY;
		} else if (state == FM_CLEAN) {
			state = sbi->p_state;
		} else
			jfs_err("updateSuper: bad state");
	} else if (sbi->state == FM_DIRTY)
		return 0;

	if ((rc = readSuper(sb, &bh)))
		return rc;

	j_sb = (struct jfs_superblock *)bh->b_data;

	j_sb->s_state = cpu_to_le32(state);
	sbi->state = state;

	if (state == FM_MOUNT) {
		
		j_sb->s_logdev = cpu_to_le32(new_encode_dev(sbi->log->bdev->bd_dev));
		j_sb->s_logserial = cpu_to_le32(sbi->log->serial);
	} else if (state == FM_CLEAN) {
		if (j_sb->s_flag & cpu_to_le32(JFS_DASD_ENABLED))
			j_sb->s_flag |= cpu_to_le32(JFS_DASD_PRIME);
	}

	mark_buffer_dirty(bh);
	sync_dirty_buffer(bh);
	brelse(bh);

	return 0;
}
Exemple #6
0
/*
 *	chkSuper()
 *
 * validate the superblock of the file system to be mounted and 
 * get the file system parameters.
 *
 * returns
 *	0 with fragsize set if check successful
 *	error code if not successful
 */
static int chkSuper(struct super_block *sb)
{
	int rc = 0;
	struct jfs_sb_info *sbi = JFS_SBI(sb);
	struct jfs_superblock *j_sb;
	struct buffer_head *bh;
	int AIM_bytesize, AIT_bytesize;
	int expected_AIM_bytesize, expected_AIT_bytesize;
	s64 AIM_byte_addr, AIT_byte_addr, fsckwsp_addr;
	s64 byte_addr_diff0, byte_addr_diff1;
	s32 bsize;

	if ((rc = readSuper(sb, &bh)))
		return rc;
	j_sb = (struct jfs_superblock *)bh->b_data;

	/*
	 * validate superblock
	 */
	/* validate fs signature */
	if (strncmp(j_sb->s_magic, JFS_MAGIC, 4) ||
	    le32_to_cpu(j_sb->s_version) > JFS_VERSION) {
		rc = -EINVAL;
		goto out;
	}

	bsize = le32_to_cpu(j_sb->s_bsize);
#ifdef _JFS_4K
	if (bsize != PSIZE) {
		jfs_err("Currently only 4K block size supported!");
		rc = -EINVAL;
		goto out;
	}
#endif				/* _JFS_4K */

	jfs_info("superblock: flag:0x%08x state:0x%08x size:0x%Lx",
		 le32_to_cpu(j_sb->s_flag), le32_to_cpu(j_sb->s_state),
		 (unsigned long long) le64_to_cpu(j_sb->s_size));

	/* validate the descriptors for Secondary AIM and AIT */
	if ((j_sb->s_flag & cpu_to_le32(JFS_BAD_SAIT)) !=
	    cpu_to_le32(JFS_BAD_SAIT)) {
		expected_AIM_bytesize = 2 * PSIZE;
		AIM_bytesize = lengthPXD(&(j_sb->s_aim2)) * bsize;
		expected_AIT_bytesize = 4 * PSIZE;
		AIT_bytesize = lengthPXD(&(j_sb->s_ait2)) * bsize;
		AIM_byte_addr = addressPXD(&(j_sb->s_aim2)) * bsize;
		AIT_byte_addr = addressPXD(&(j_sb->s_ait2)) * bsize;
		byte_addr_diff0 = AIT_byte_addr - AIM_byte_addr;
		fsckwsp_addr = addressPXD(&(j_sb->s_fsckpxd)) * bsize;
		byte_addr_diff1 = fsckwsp_addr - AIT_byte_addr;
		if ((AIM_bytesize != expected_AIM_bytesize) ||
		    (AIT_bytesize != expected_AIT_bytesize) ||
		    (byte_addr_diff0 != AIM_bytesize) ||
		    (byte_addr_diff1 <= AIT_bytesize))
			j_sb->s_flag |= cpu_to_le32(JFS_BAD_SAIT);
	}

	if ((j_sb->s_flag & cpu_to_le32(JFS_GROUPCOMMIT)) !=
	    cpu_to_le32(JFS_GROUPCOMMIT))
		j_sb->s_flag |= cpu_to_le32(JFS_GROUPCOMMIT);

	/* validate fs state */
	if (j_sb->s_state != cpu_to_le32(FM_CLEAN) &&
	    !(sb->s_flags & MS_RDONLY)) {
		jfs_err("jfs_mount: Mount Failure: File System Dirty.");
		rc = -EINVAL;
		goto out;
	}

	sbi->state = le32_to_cpu(j_sb->s_state);
	sbi->mntflag = le32_to_cpu(j_sb->s_flag);

	/*
	 * JFS always does I/O by 4K pages.  Don't tell the buffer cache
	 * that we use anything else (leave s_blocksize alone).
	 */
	sbi->bsize = bsize;
	sbi->l2bsize = le16_to_cpu(j_sb->s_l2bsize);

	/*
	 * For now, ignore s_pbsize, l2bfactor.  All I/O going through buffer
	 * cache.
	 */
	sbi->nbperpage = PSIZE >> sbi->l2bsize;
	sbi->l2nbperpage = L2PSIZE - sbi->l2bsize;
	sbi->l2niperblk = sbi->l2bsize - L2DISIZE;
	if (sbi->mntflag & JFS_INLINELOG)
		sbi->logpxd = j_sb->s_logpxd;
	else {
		sbi->logdev = new_decode_dev(le32_to_cpu(j_sb->s_logdev));
		memcpy(sbi->uuid, j_sb->s_uuid, sizeof(sbi->uuid));
		memcpy(sbi->loguuid, j_sb->s_loguuid, sizeof(sbi->uuid));
	}
	sbi->fsckpxd = j_sb->s_fsckpxd;
	sbi->ait2 = j_sb->s_ait2;

      out:
	brelse(bh);
	return rc;
}
Exemple #7
0
/*
 * NAME:	jfs_statfs(vfsp, sfsp, crp)
 *
 * FUNCTION:	get file system status <sfsp> from vfs <vfsp>
 *
 * PARAMETER:	vfsp	- virtual file system
 *		sfsp	- file status information structure
 *		crp	- credential
 *
 * RETURN:	zero on success, non-zero on failure
 *			
 * serialization: statfs() and extendfs() serializes by inode lock
 *	of the inode map for both inode map and block allocation map. 
 *	All other access to fragment allocation map is serialized 
 *	under VMM locking.
 *
 * note: percolation of file system information:
 * support struct statfs (sys/statfs.h) for get file system status
 * service call statfs().
 * (XPG4.2 defines struct statvfs in sys/statvfs.h for statvfs()
 * which requires statfs() and additional information)
 */
jfs_statfs(
	register struct vfs	*vfsp,
	register struct statfs	*statfsp,
	struct ucred		*crp)
{
	register int32	rc;
	register inode_t *ipmnt;	/* mount inode */
	inode_t	*ipimap, *ipbmap;
	cbuf_t	*bpsuper;
	struct superblock *sb = NULL;
	int32	fsck_length, log_length;

NOISE(1,("jfs_statfs: vfs:0x%08x\n", vfsp));

	/*
	 * get the file system stats from the superblock
	 */
	ipimap = (struct inode *)vfsp->vfs_data;
	ipmnt = ipimap->i_ipmnt;
	if (rc = readSuper(ipmnt, &bpsuper))
		goto out;
	sb = (struct superblock *)(bpsuper->cm_cdata);

/*
	bcopy(sb->s_fname, statfsp->f_fname, sizeof(sb->s_fname));
*/
	bcopy(sb->s_fpack, statfsp->f_fpack, sizeof(sb->s_fpack));
	statfsp->f_bsize = PSIZE; /* preferred i/o block size */
	statfsp->f_fsize = sb->s_bsize; /* fundamental block size */
	fsck_length = lengthPXD(&(sb->s_fsckpxd));
	log_length = lengthPXD(&(sb->s_logpxd));

	rawRelease(bpsuper);

 	/* statfs()/extendfs() serialized by inode lock of the inode map 
	 * for both inode map and block allocation map. 
	 */
	IREAD_LOCK(ipimap);

	/*
	 * get the block stats from the bmap
	 */
	ipbmap = ipmnt->i_ipbmap;
	statfsp->f_blocks = (ipbmap->i_bmap->db_mapsize + fsck_length +
				log_length) >> ipbmap->i_bmap->db_l2nbperpage;
	statfsp->f_bfree = statfsp->f_bavail =
		ipbmap->i_bmap->db_nfree >> ipbmap->i_bmap->db_l2nbperpage;

	/*
	 * get the file stats from the ipimap
	 */
	statfsp->f_files = ipimap->i_imap->im_numinos;
	statfsp->f_ffree = ipimap->i_imap->im_numfree;

	/*
	 * fill in from vfs
	 */
	statfsp->f_fsid = vfsp->vfs_fsid;
	statfsp->f_vfstype = MNT_XJFS;
	statfsp->f_vfsnumber = vfsp->vfs_number;
	statfsp->f_name_max = JFS_NAME_MAX;

	/*
	 * fields in the statfs structure that we don't fill in ...
	 *
	long f_version;		version/type of statfs, 0 for now
	long f_type;		type of info, 0 for now
	long f_vfsoff;		reserved, for vfs specific data offset
	long f_vfslen;		reserved, for len of vfs specific data
	long f_vfsvers;		reserved, for vers of vfs specific data
	 */

out:
	IREAD_UNLOCK(ipimap);

	return rc;
}