void simplefs_inode_add(struct super_block *vsb, struct simplefs_inode *inode) { struct simplefs_super_block *sb = SIMPLEFS_SB(vsb); struct buffer_head *bh; struct simplefs_inode *inode_iterator; if (mutex_lock_interruptible(&simplefs_inodes_mgmt_lock)) { sfs_trace("Failed to acquire mutex lock\n"); return; } bh = sb_bread(vsb, SIMPLEFS_INODESTORE_BLOCK_NUMBER); BUG_ON(!bh); inode_iterator = (struct simplefs_inode *)bh->b_data; if (mutex_lock_interruptible(&simplefs_sb_lock)) { sfs_trace("Failed to acquire mutex lock\n"); return; } /* Append the new inode in the end in the inode store */ inode_iterator += sb->inodes_count; memcpy(inode_iterator, inode, sizeof(struct simplefs_inode)); sb->inodes_count++; mark_buffer_dirty(bh); simplefs_sb_sync(vsb); brelse(bh); mutex_unlock(&simplefs_sb_lock); mutex_unlock(&simplefs_inodes_mgmt_lock); }
/* This function returns a blocknumber which is free. * The block will be removed from the freeblock list. * * In an ideal, production-ready filesystem, we will not be dealing with blocks, * and instead we will be using extents * * If for some reason, the file creation/deletion failed, the block number * will still be marked as non-free. You need fsck to fix this.*/ int simplefs_sb_get_a_freeblock(struct super_block *vsb, uint64_t * out) { struct simplefs_super_block *sb = SIMPLEFS_SB(vsb); int i; int ret = 0; if (mutex_lock_interruptible(&simplefs_sb_lock)) { printk(KERN_ERR "Failed to acquire mutex lock %s +%d\n", __FILE__, __LINE__); ret = -EINTR; goto end; } /* Loop until we find a free block. We start the loop from 3, * as all prior blocks will always be in use */ for (i = 3; i < SIMPLEFS_MAX_FILESYSTEM_OBJECTS_SUPPORTED; i++) { if (sb->free_blocks & (1 << i)) { break; } } if (unlikely(i == SIMPLEFS_MAX_FILESYSTEM_OBJECTS_SUPPORTED)) { printk(KERN_ERR "No more free blocks available"); ret = -ENOSPC; goto end; } *out = i; /* Remove the identified block from the free list */ sb->free_blocks &= ~(1 << i); simplefs_sb_sync(vsb); end: mutex_unlock(&simplefs_sb_lock); return ret; }