Example #1
0
/**
 * wakeup function of logging process
 * @param __data     : super block
 */
void rfs_log_wakeup(unsigned long __data)
{
       struct super_block *sb = (struct super_block *) __data;
       struct task_struct *p = RFS_SB(sb)->sleep_proc;

       mod_timer(&RFS_SB(sb)->timer, DATA_EXPIRES(jiffies));
       if (p->state == TASK_UNINTERRUPTIBLE)
               wake_up_process(p);
}
Example #2
0
/**
 *  read dir entry in specified directory
 * @param inode                specified directory inode
 * @param bh           buffer head to read dir entries
 * @param ppos         entry position to read
 * @param[out] dir_info        to save dir entry info
 * @return             return 0 on success, errno on failure
 */
static int internal_readdir(struct inode *inode, struct buffer_head **bh, loff_t *ppos, struct rfs_dir_info *dir_info)
{
#ifdef CONFIG_RFS_VFAT
       unsigned short uname[UNICODE_NAME_LENGTH];
#endif
       struct rfs_dir_entry *ep = NULL;
       loff_t index = *ppos;
       unsigned long ino;
       unsigned int type;
       int err;

       while (1) {
               ep = get_entry(inode, (u32) index, bh);
               if (IS_ERR(ep)) 
                       return PTR_ERR(ep);

               index++;

               type = entry_type(ep);

               dir_info->type = type;

               if (type == TYPE_UNUSED) 
                       return -INTERNAL_EOF; /* not error case */

               if ((type == TYPE_DELETED) || (type == TYPE_EXTEND) || 
                               (type == TYPE_VOLUME))
                       continue;

#ifdef CONFIG_RFS_VFAT
               uname[0] = 0x0;
               get_uname_from_entry(inode, index - 1, uname);
               if (uname[0] == 0x0 || !IS_VFAT(RFS_SB(inode->i_sb))) 
                       convert_dosname_to_cstring(dir_info->name, ep->name, ep->sysid);        
               else 
                       convert_uname_to_cstring(dir_info->name, uname, RFS_SB(inode->i_sb)->nls_disk);
#else
               convert_dosname_to_cstring(dir_info->name, ep->name, ep->sysid);
#endif

               err = rfs_iunique(inode, index - 1, &ino);
               if (err)
                       return err;
               dir_info->ino = ino;

               *ppos = index;
                       
               return 0;

       }

       return 0;
}
Example #3
0
/**
 *  rfs_direct_IO - directly read/write from/to user space buffers without cache
 * @param rw           read/write type
 * @param inode                inode
 * @param iobuf                iobuf
 * @param blocknr      number of blocks
 * @param blocksize    block size
 * @return             write/read size on success, errno on failure
 */
int rfs_direct_IO(int rw, struct inode *inode, struct kiobuf *iobuf, unsigned long blocknr, int blocksize)
{
       struct super_block *sb = inode->i_sb;
       loff_t offset, old_size = inode->i_size;
       unsigned int alloc_clus = 0;
       int zerofilled = FALSE, ret;

       offset = blocknr << sb->s_blocksize_bits;

       if (rw == WRITE) {
               unsigned int clu_size, clu_bits;
               unsigned int req_clus, free_clus;

               clu_size = RFS_SB(sb)->cluster_size;
               clu_bits = RFS_SB(sb)->cluster_bits;

               /* compare the number of required clusters with free clusters */
               alloc_clus = (inode->i_size + clu_size - 1) >> clu_bits;
               req_clus = (offset + iobuf->length + clu_size - 1) >> clu_bits;
               if (req_clus > alloc_clus)
                       req_clus -= alloc_clus; /* required clusters */
               else 
                       req_clus = 0;

               if (rfs_log_start(inode->i_sb, RFS_LOG_WRITE, inode))
                       return -EIO;

               free_clus = GET_FREE_CLUS(RFS_SB(sb));
               if (req_clus > free_clus) {
                       DEBUG(DL1, "req_clus = %d free_clus = %d \n", 
                                       req_clus, free_clus);
                       ret = -ENOSPC;
                       goto end_log;
               }

               /* lseek case in direct IO */
               if (offset > old_size) {
                       /* 
                        * NOTE: In spite of direc IO, 
                        * we use page cache for extend_with_zeorfill 
                        */
                       ret = extend_with_zerofill(inode, 
                                       (u32) old_size, (u32) offset);
                       if (ret)
                               goto end_log;

                       inode->i_size = offset;
                       set_mmu_private(inode, offset);
                       zerofilled = TRUE;
               }
       }