コード例 #1
0
struct inode * ext_new_inode(const struct inode * dir)
{
	struct super_block * sb;
	struct inode * inode;
	struct ext_free_inode * efi;
	unsigned long block;
	int j;

	if (!dir || !(inode=get_empty_inode()))
		return NULL;
	sb = dir->i_sb;
	inode->i_sb = sb;
	inode->i_flags = sb->s_flags;
	if (!sb->u.ext_sb.s_firstfreeinodeblock)
		return 0;
	lock_super (sb);
	efi = ((struct ext_free_inode *) sb->u.ext_sb.s_firstfreeinodeblock->b_data) +
		(sb->u.ext_sb.s_firstfreeinodenumber-1)%EXT_INODES_PER_BLOCK;
	if (efi->count) {
		j = efi->free[--efi->count];
		mark_buffer_dirty(sb->u.ext_sb.s_firstfreeinodeblock, 1);
	} else {
#ifdef EXTFS_DEBUG
printk("ext_free_inode: inode empty, skipping to %d\n", efi->next);
#endif
		j = sb->u.ext_sb.s_firstfreeinodenumber;
		if (efi->next > sb->u.ext_sb.s_ninodes) {
			printk ("efi->next = %ld\n", efi->next);
			panic ("ext_new_inode: bad inode number in free list\n");
		}
		sb->u.ext_sb.s_firstfreeinodenumber = efi->next;
		block = 2 + (((unsigned long) efi->next) - 1) / EXT_INODES_PER_BLOCK;
		brelse (sb->u.ext_sb.s_firstfreeinodeblock);
		if (!sb->u.ext_sb.s_firstfreeinodenumber) {
			sb->u.ext_sb.s_firstfreeinodeblock = NULL;
		} else {
			if (!(sb->u.ext_sb.s_firstfreeinodeblock =
			    bread(sb->s_dev, block, sb->s_blocksize)))
				panic ("ext_new_inode: unable to read next free inode block\n");
		}
	}
	sb->u.ext_sb.s_freeinodescount --;
	sb->s_dirt = 1;
	inode->i_count = 1;
	inode->i_nlink = 1;
	inode->i_dev = sb->s_dev;
	inode->i_uid = current->fsuid;
	inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
	inode->i_dirt = 1;
	inode->i_ino = j;
	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
	inode->i_op = NULL;
	inode->i_blocks = inode->i_blksize = 0;
	insert_inode_hash(inode);
#ifdef EXTFS_DEBUG
printk("ext_new_inode : allocating inode %d\n", inode->i_ino);
#endif
	unlock_super (sb);
	return inode;
}
コード例 #2
0
ファイル: inode.c プロジェクト: lithoxs/elks
struct inode *new_inode(register struct inode *dir, __u16 mode)
{
    register struct inode *inode;

    if (!(inode = get_empty_inode()))
	return inode;
    inode->i_gid =(__u8) current->egid;
    if (dir) {
	inode->i_sb = dir->i_sb;
	inode->i_dev = inode->i_sb->s_dev;
	inode->i_flags = inode->i_sb->s_flags;
	if (dir->i_mode & S_ISGID) {
	    inode->i_gid = dir->i_gid;
	    if (S_ISDIR(mode))
		mode |= S_ISGID;
	}
    }

    if (S_ISLNK(mode))
	mode |= 0777;
    else
	mode &= ~(current->fs.umask & 0777);
    inode->i_mode = mode;
    inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;

#ifdef BLOAT_FS
    inode->i_blocks = inode->i_blksize = 0;
#endif

    set_ops(inode);
    return inode;
}
コード例 #3
0
ファイル: pipe.c プロジェクト: chinnyannieb/empeg-hijack
static struct inode * get_pipe_inode(void)
{
	extern struct inode_operations pipe_inode_operations;
	struct inode *inode = get_empty_inode();

	if (inode) {
		unsigned long page = __get_free_page(GFP_USER);

		if (!page) {
			iput(inode);
			inode = NULL;
		} else {
			PIPE_BASE(*inode) = (char *) page;
			inode->i_op = &pipe_inode_operations;
			PIPE_WAIT(*inode) = NULL;
			PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
			PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0;
			PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1;
			PIPE_LOCK(*inode) = 0;
			/*
			 * Mark the inode dirty from the very beginning,
			 * that way it will never be moved to the dirty
			 * list because "mark_inode_dirty()" will think
			 * that it already _is_ on the dirty list.
			 */
			inode->i_state = I_DIRTY;
			inode->i_mode = S_IFIFO | S_IRUSR | S_IWUSR;
			inode->i_uid = current->fsuid;
			inode->i_gid = current->fsgid;
			inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
			inode->i_blksize = PAGE_SIZE;
		}
	}
	return inode;
}
コード例 #4
0
ファイル: super.c プロジェクト: chinnyannieb/empeg-hijack
static int umount_dev(kdev_t dev, int flags)
{
	int retval;
	struct inode * inode = get_empty_inode();

	retval = -ENOMEM;
	if (!inode)
		goto out;

	inode->i_rdev = dev;
	retval = -ENXIO;
	if (MAJOR(dev) >= MAX_BLKDEV)
		goto out_iput;

	fsync_dev(dev);

	down(&mount_sem);

	retval = do_umount(dev, 0, flags);
	if (!retval) {
		fsync_dev(dev);
		if (dev != ROOT_DEV) {
			blkdev_release(inode);
			put_unnamed_dev(dev);
		}
	}

	up(&mount_sem);
out_iput:
	iput(inode);
out:
	return retval;
}
コード例 #5
0
ファイル: inode.c プロジェクト: lkundrak/elks
struct inode *__iget(register struct super_block *sb,
		     ino_t inr /*,int crossmntp */ )
{
    int i;
    register struct inode *inode;
    register struct inode *empty = NULL;

    debug3("iget called(%x, %d, %d)\n", sb, inr, 0 /* crossmntp */ );
    if (!sb)
	panic("VFS: iget with sb==NULL");
  repeat:
    inode = inode_block;
    for (i = NR_INODE; i; i--, inode++) {
	if (inode->i_dev == sb->s_dev && inode->i_ino == inr) {
	    goto found_it;
	}
    }

    if (!empty) {
	debug("iget: getting an empty inode...\n");
	empty = get_empty_inode();
	debug1("iget: got one... (%x)!\n", empty);
	if (empty)
	    goto repeat;
	return NULL;
    }
    inode = empty;
    inode->i_sb = sb;
    inode->i_dev = sb->s_dev;
    inode->i_ino = inr;
    inode->i_flags = ((unsigned short int) sb->s_flags);
    put_last_free(inode);
    debug("iget: Reading inode\n");
    read_inode(inode);
    debug("iget: Read it\n");
    goto return_it;

  found_it:
    if (!inode->i_count)
	nr_free_inodes--;
    inode->i_count++;
    wait_on_inode(inode);
    if (inode->i_dev != sb->s_dev || inode->i_ino != inr) {
	printk("Whee.. inode changed from under us. Tell _.\n");
	iput(inode);
	goto repeat;
    }
    if ( /* crossmntp && */ inode->i_mount) {
	struct inode *tmp = inode->i_mount;
	tmp->i_count++;
	iput(inode);
	inode = tmp;
	wait_on_inode(inode);
    }
    if (empty)
	iput(empty);

  return_it:
    return inode;
}
コード例 #6
0
ファイル: inode.c プロジェクト: lkundrak/elks
struct inode *get_pipe_inode(void)
{
    register struct inode *inode;
    extern struct inode_operations pipe_inode_operations;

    if ((inode = get_empty_inode())) {
	if (!(PIPE_BASE(*inode) = get_pipe_mem())) {
	    iput(inode);
	    return NULL;
	}
	inode->i_op = &pipe_inode_operations;
	inode->i_count = 2;	/* sum of readers/writers */
	PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
	PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0;
	PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1;
	PIPE_LOCK(*inode) = 0;
	inode->i_pipe = 1;
	inode->i_mode |= S_IFIFO | S_IRUSR | S_IWUSR;
	inode->i_uid = current->euid;
	inode->i_gid = (__u8) current->egid;
	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;

#if 0
	inode->i_blksize = PAGE_SIZE;
#endif

    }
    return inode;
}
コード例 #7
0
ファイル: fs.c プロジェクト: chinnyannieb/empeg-hijack
static int
_linux_ntfs_mkdir(struct inode *dir, struct dentry* d, int mode)
{
	int error;
	struct inode *r = 0;
	ntfs_volume *vol;
	ntfs_inode *ino;
	ntfs_attribute *si;

	ntfs_debug (DEBUG_DIR1, "mkdir %s in %x\n",d->d_name.name, dir->i_ino);
	error = ENAMETOOLONG;
	if (d->d_name.len > /* FIXME */255)
		goto out;

	error = EIO;
	r = get_empty_inode();
	if (!r)
		goto out;
	
	vol = NTFS_INO2VOL(dir);
#ifdef NTFS_IN_LINUX_KERNEL
	ino = NTFS_LINO2NINO(r);
#else
	ino = ntfs_malloc(sizeof(ntfs_inode));
	error = ENOMEM;
	if(!ino)
		goto out;
	r->u.generic_ip = ino;
#endif
	error = ntfs_mkdir(NTFS_LINO2NINO(dir), 
			   d->d_name.name, d->d_name.len, ino);
	if(error)
		goto out;
	r->i_uid = vol->uid;
	r->i_gid = vol->gid;
	r->i_nlink = 1;
	r->i_sb = dir->i_sb;
	si = ntfs_find_attr(ino,vol->at_standard_information,NULL);
	if(si){
		char *attr = si->d.data;
		r->i_atime = ntfs_ntutc2unixutc(NTFS_GETU64(attr+0x18));
		r->i_ctime = ntfs_ntutc2unixutc(NTFS_GETU64(attr));
		r->i_mtime = ntfs_ntutc2unixutc(NTFS_GETU64(attr+8));
	}
	/* It's a directory */
	r->i_op = &ntfs_dir_inode_operations;
	r->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
#ifdef CONFIG_NTFS_RW
	r->i_mode|=S_IWUGO;
#endif
	r->i_mode &= ~vol->umask;	
	
	insert_inode_hash(r);
	d_instantiate(d, r);
	error = 0;
 out:
 	ntfs_debug (DEBUG_DIR1, "mkdir returns %d\n", -error);
	return -error;
}
コード例 #8
0
ファイル: socket.c プロジェクト: wanggx/Linux1.0
/* 查找一个空闲的struct socket结构,并初始化相应的关系
 * 如sock中有inode节点指针,inode中有struct socket指针
 * wait表示在获取socket结构的时候,该函数是不是阻塞的,
 * wait>0表示阻塞,=0表示非阻塞
 */
static struct socket *sock_alloc(int wait)
{
  struct socket *sock;

  while (1) {
	cli();
	for (sock = sockets; sock <= last_socket; ++sock) {
		if (sock->state == SS_FREE) {
			/* 注意在socket系统调用完成后struct socket的状态为SS_UNCONNECTED */
			sock->state = SS_UNCONNECTED;
			sti();
			sock->flags = 0;
			sock->ops = NULL;
			sock->data = NULL;
			sock->conn = NULL;
			sock->iconn = NULL;

			/*
			 * This really shouldn't be necessary, but everything
			 * else depends on inodes, so we grab it.
			 * Sleeps are also done on the i_wait member of this
			 * inode.  The close system call will iput this inode
			 * for us.
			 */
			/* 此处给socket分配了一个inode,但是inode是空的,
			 * 并没有包含有效数据的 
			 */
			if (!(SOCK_INODE(sock) = get_empty_inode())) {
				printk("NET: sock_alloc: no more inodes\n");
				sock->state = SS_FREE;
				return(NULL);
			}
			/* 此时设置inode和socket之间的关系,
			 * S_IFSOCK指明inode指向的时socket文件 
			 */
			SOCK_INODE(sock)->i_mode = S_IFSOCK;
			SOCK_INODE(sock)->i_uid = current->euid;
			SOCK_INODE(sock)->i_gid = current->egid;
			SOCK_INODE(sock)->i_socket = sock;

			sock->wait = &SOCK_INODE(sock)->i_wait;
			DPRINTF((net_debug,
				"NET: sock_alloc: sk 0x%x, ino 0x%x\n",
				       			sock, SOCK_INODE(sock)));
			return(sock);
		}
	}
	sti();
	if (!wait) return(NULL);
	DPRINTF((net_debug, "NET: sock_alloc: no free sockets, sleeping...\n"));
	/* 如果没找到,则在socket_wait_free队列中睡眠,当有释放时,则唤醒该进程 */
	interruptible_sleep_on(&socket_wait_free);
	if (current->signal & ~current->blocked) {
		DPRINTF((net_debug, "NET: sock_alloc: sleep was interrupted\n"));
		return(NULL);
	}
	DPRINTF((net_debug, "NET: sock_alloc: wakeup... trying again...\n"));
  }
}
コード例 #9
0
ファイル: inode.c プロジェクト: lithoxs/elks
struct inode *__iget(register struct super_block *sb,
		     ino_t inr /*,int crossmntp */ )
{
    register struct inode *inode;

    debug3("iget called(%x, %d, %d)\n", sb, inr, 0 /* crossmntp */ );
    if (!sb)
	panic("VFS: iget with sb==NULL");

  repeat:
    do {
	inode = first_inode;
	do {
	    if (inode->i_dev == sb->s_dev && inode->i_ino == inr)
		goto found_it;
	} while ((inode = inode->i_prev) != first_inode);
	debug("iget: getting an empty inode...\n");
    } while (!(inode = get_empty_inode()));
    debug1("iget: got one... (%x)!\n", empty);

    inode->i_sb = sb;
    inode->i_dev = sb->s_dev;
    inode->i_flags = ((unsigned short int) sb->s_flags);
    inode->i_ino = inr;
    put_last_lru(inode);
    debug("iget: Reading inode\n");
    read_inode(inode);
    debug("iget: Read it\n");
    goto return_it;

  found_it:
    if (!inode->i_count)
	nr_free_inodes--;
    inode->i_count++;
    wait_on_inode(inode);
    if (inode->i_dev != sb->s_dev || inode->i_ino != inr) {
	printk("Whee.. inode changed from under us. Tell _.\n");
	iput(inode);
	goto repeat;
    }
    if ( /* crossmntp && */ inode->i_mount) {
	struct inode *tmp = inode->i_mount;
	tmp->i_count++;
	iput(inode);
	inode = tmp;
	wait_on_inode(inode);
    }

  return_it:
    return inode;
}
コード例 #10
0
ファイル: socket.c プロジェクト: binsys/doc-linux
static struct socket *
sock_alloc(int wait)
{
	struct socket *sock;

	while (1) {
		cli();
		for (sock = sockets; sock <= last_socket; ++sock)
			if (sock->state == SS_FREE) {
				sock->state = SS_UNCONNECTED;
				sti();
				sock->flags = 0;
				sock->ops = NULL;
				sock->data = NULL;
				sock->conn = NULL;
				sock->iconn = NULL;
				/*
				 * this really shouldn't be necessary, but
				 * everything else depends on inodes, so we
				 * grab it.
				 * sleeps are also done on the i_wait member
				 * of this inode.
				 * the close system call will iput this inode
				 * for us.
				 */
				if (!(SOCK_INODE(sock) = get_empty_inode())) {
					printk("sock_alloc: no more inodes\n");
					sock->state = SS_FREE;
					return NULL;
				}
				SOCK_INODE(sock)->i_mode = S_IFSOCK;
				sock->wait = &SOCK_INODE(sock)->i_wait;
				PRINTK("sock_alloc: socket 0x%x, inode 0x%x\n",
				       sock, SOCK_INODE(sock));
				return sock;
			}
		sti();
		if (!wait)
			return NULL;
		PRINTK("sock_alloc: no free sockets, sleeping...\n");
		interruptible_sleep_on(&socket_wait_free);
		if (current->signal & ~current->blocked) {
			PRINTK("sock_alloc: sleep was interrupted\n");
			return NULL;
		}
		PRINTK("sock_alloc: wakeup... trying again...\n");
	}
}
コード例 #11
0
ファイル: inode.c プロジェクト: chinnyannieb/empeg-hijack
struct inode *
affs_new_inode(const struct inode *dir)
{
	struct inode		*inode;
	struct super_block	*sb;
	s32			 block;

	if (!dir || !(inode = get_empty_inode()))
		return NULL;

	sb = dir->i_sb;
	inode->i_sb    = sb;
	inode->i_flags = 0;

	if (!(block = affs_new_header((struct inode *)dir))) {
		iput(inode);
		return NULL;
	}

	inode->i_count   = 1;
	inode->i_nlink   = 1;
	inode->i_dev     = sb->s_dev;
	inode->i_uid     = current->fsuid;
	inode->i_gid     = current->fsgid;
	inode->i_ino     = block;
	inode->i_op      = NULL;
	inode->i_blocks  = 0;
	inode->i_size    = 0;
	inode->i_mode    = 0;
	inode->i_blksize = 0;
	inode->i_mtime   = inode->i_atime = inode->i_ctime = CURRENT_TIME;

	inode->u.affs_i.i_original  = 0;
	inode->u.affs_i.i_parent    = dir->i_ino;
	inode->u.affs_i.i_zone      = 0;
	inode->u.affs_i.i_hlink     = 0;
	inode->u.affs_i.i_pa_cnt    = 0;
	inode->u.affs_i.i_pa_next   = 0;
	inode->u.affs_i.i_pa_last   = 0;
	inode->u.affs_i.i_ec        = NULL;
	inode->u.affs_i.i_lastblock = -1;

	insert_inode_hash(inode);
	mark_inode_dirty(inode);

	return inode;
}
コード例 #12
0
ファイル: namei.c プロジェクト: chinnyannieb/empeg-hijack
int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode)
{
  int error;
  struct inode * inode;
  struct reiserfs_dir_entry de;
  int windex ;
  int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 ;
  struct reiserfs_transaction_handle th ;
  int err;
	
  if (!dir)
    return -ENOENT;
	
  inode = get_empty_inode() ;
  if (!inode) {
    return -ENOSPC ;
  }
  journal_begin(&th, dir->i_sb, jbegin_count) ;
  th.t_caller = "create" ;
  windex = push_journal_writer("reiserfs_create") ;
  inode = reiserfs_new_inode (&th, dir, mode, 0, dentry, inode, &err);
  if (!inode) {
    pop_journal_writer(windex) ;
    journal_end(&th, dir->i_sb, jbegin_count) ;
    return err;
  }
  reiserfs_update_inode_transaction(inode) ;
  reiserfs_update_inode_transaction(dir) ;
	
  inode->i_op = &reiserfs_file_inode_operations;
  inode->i_mode = mode;

  error = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, INODE_PKEY (inode), &de, 1);
  if (error) {
    inode->i_nlink--;
    if_in_ram_update_sd (&th, inode);
    pop_journal_writer(windex) ;
    journal_end(&th, dir->i_sb, jbegin_count) ;
    iput (inode);
    return error;
  }
  if_in_ram_update_sd (&th, dir); 
  d_instantiate(dentry, inode);
  pop_journal_writer(windex) ;
  journal_end(&th, dir->i_sb, jbegin_count) ;
  return 0;
}
コード例 #13
0
ファイル: inode.c プロジェクト: chinnyannieb/empeg-hijack
struct inode*
ftp_iget(struct super_block* sb, struct ftp_fattr *fattr){
	struct inode *res;

//	DEBUG(" Hangin' in here!\n");

	res = get_empty_inode();
	res->i_sb = sb;
	res->i_dev = sb->s_dev;
	res->i_ino = fattr->f_ino;
	res->u.generic_ip = NULL;
	ftp_set_inode_attr(res,fattr);
	if(S_ISDIR(res->i_mode)){
//		DEBUG(" yup, it's a dir!\n");
		res->i_op = &ftp_dir_inode_operations;
	}else res->i_op = &ftp_file_inode_operations;
	
	insert_inode_hash(res);
	
	return res;
}
コード例 #14
0
/*
 * This is our own version of iget that looks up inodes by file handle
 * instead of inode number.  We use this technique instead of using
 * the vfs read_inode function because there is no way to pass the
 * file handle or current attributes into the read_inode function.
 *
 * We provide a special check for NetApp .snapshot directories to avoid
 * inode aliasing problems. All snapshot inodes are anonymous (unhashed).
 */
struct inode *
nfs_fhget(struct dentry *dentry, struct nfs_fh *fhandle,
          struct nfs_fattr *fattr)
{
    struct super_block *sb = dentry->d_sb;

    dprintk("NFS: nfs_fhget(%s/%s fileid=%d)\n",
            dentry->d_parent->d_name.name, dentry->d_name.name,
            fattr->fileid);

    /* Install the file handle in the dentry */
    *((struct nfs_fh *) dentry->d_fsdata) = *fhandle;

#ifdef CONFIG_NFS_SNAPSHOT
    /*
     * Check for NetApp snapshot dentries, and get an
     * unhashed inode to avoid aliasing problems.
     */
    if ((dentry->d_parent->d_inode->u.nfs_i.flags & NFS_IS_SNAPSHOT) ||
            (dentry->d_name.len == 9 &&
             memcmp(dentry->d_name.name, ".snapshot", 9) == 0)) {
        struct inode *inode = get_empty_inode();
        if (!inode)
            goto out;
        inode->i_sb = sb;
        inode->i_dev = sb->s_dev;
        inode->i_flags = 0;
        inode->i_ino = fattr->fileid;
        nfs_read_inode(inode);
        nfs_fill_inode(inode, fattr);
        inode->u.nfs_i.flags |= NFS_IS_SNAPSHOT;
        dprintk("NFS: nfs_fhget(snapshot ino=%ld)\n", inode->i_ino);
out:
        return inode;
    }
#endif
    return __nfs_fhget(sb, fattr);
}
コード例 #15
0
ファイル: namei.c プロジェクト: chinnyannieb/empeg-hijack
int reiserfs_symlink (struct inode * dir, struct dentry * dentry, const char * symname)
{
  struct inode * inode;
  struct path path_to_entry;
  struct reiserfs_dir_entry de;
  int error;
  int windex ;
  struct reiserfs_transaction_handle th ;
  int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 
  int err;

  init_path (&path_to_entry);
  if (strlen (symname) + 1 + SD_SIZE > MAX_ITEM_LEN (dir->i_sb->s_blocksize)) {
    return -ENAMETOOLONG;
  }
  inode = get_empty_inode() ;
  if (!inode) {
    return -ENOSPC ;
  }
 
  journal_begin(&th, dir->i_sb, jbegin_count) ;
  windex = push_journal_writer("reiserfs_symlink") ;
  inode = reiserfs_new_inode (&th, dir, S_IFLNK, symname, dentry, inode, &err);
  if (inode == 0) {
    pop_journal_writer(windex) ;
    journal_end(&th, dir->i_sb, jbegin_count) ;
    return err;
  }
  reiserfs_update_inode_transaction(inode) ;
  reiserfs_update_inode_transaction(dir) ;

  inode->i_op = &reiserfs_symlink_inode_operations;
  inode->i_size = strlen (symname);
  inode->i_mode = S_IFLNK | 0777;
  if_in_ram_update_sd (&th, inode);

  de.de_gen_number_bit_string = 0;
  if (reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path_to_entry, &de) == POSITION_FOUND) {
    pathrelse (&path_to_entry);
    inode->i_nlink--;
    if_in_ram_update_sd (&th, inode);
    pop_journal_writer(windex) ;
    journal_end(&th, dir->i_sb, jbegin_count) ;
    iput (inode);
    return -EEXIST;
  }
  pathrelse (&path_to_entry);

  error = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, INODE_PKEY (inode), &de, 1);
  if (error) {
    inode->i_nlink--;
    if_in_ram_update_sd (&th, inode);
    pop_journal_writer(windex) ;
    journal_end(&th, dir->i_sb, jbegin_count) ;
    iput (inode);
    return error;
  }
  if_in_ram_update_sd (&th, dir);
  d_instantiate(dentry, inode);
  pop_journal_writer(windex) ;
  journal_end(&th, dir->i_sb, jbegin_count) ;
  return 0;
}
コード例 #16
0
ファイル: namei.c プロジェクト: chinnyannieb/empeg-hijack
int reiserfs_mkdir (struct inode * dir, struct dentry *dentry, int mode)
{
  int error;
  struct inode * inode;
  struct path path_to_entry;
  struct reiserfs_dir_entry de;
  int windex ;
  struct reiserfs_transaction_handle th ;
  int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 
  int err;


  init_path (&path_to_entry);
  if (!dir || !dir->i_sb) {
    return -EINVAL;
  }
  inode = get_empty_inode() ;
  if (!inode) {
    return -ENOSPC ;
  }

  journal_begin(&th, dir->i_sb, jbegin_count) ;
  windex = push_journal_writer("reiserfs_mkdir") ;
  de.de_gen_number_bit_string = 0;
  if (reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path_to_entry, &de) == POSITION_FOUND) {
    pathrelse (&path_to_entry);
    pop_journal_writer(windex) ;
    journal_end(&th, dir->i_sb, jbegin_count) ;
    iput(inode) ;
    return -EEXIST;
  }
  pathrelse (&path_to_entry);
  
  if (dir->i_nlink >= REISERFS_LINK_MAX) {
    pop_journal_writer(windex) ;
    journal_end(&th, dir->i_sb, jbegin_count) ;
    iput(inode) ;
    return -EMLINK;
  }
  
  mode = S_IFDIR | (mode & 0777 & ~current->fs->umask);
  if (dir->i_mode & S_ISGID)
    mode |= S_ISGID;
  inode = reiserfs_new_inode (&th, dir, mode, 0, dentry, inode, &err);
  if (!inode) {
    pop_journal_writer(windex) ;
    journal_end(&th, dir->i_sb, jbegin_count) ;
    return err;
  }
  reiserfs_update_inode_transaction(inode) ;
  reiserfs_update_inode_transaction(dir) ;

  inode->i_op = &reiserfs_dir_inode_operations;

  /* new inode and stat data are uptodate. Inode is clean. */
  error = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, INODE_PKEY (inode), &de, 1);
  if (error) {
    inode->i_nlink = 0;
    if_in_ram_update_sd (&th, inode);
    pop_journal_writer(windex) ;
    journal_end(&th, dir->i_sb, jbegin_count) ;
    iput (inode);
    return error;
  }

  /* update dir inode, reiserfs_add_entry does not do that */
  dir->i_nlink ++;
  if_in_ram_update_sd (&th, dir);
  d_instantiate(dentry, inode);
  pop_journal_writer(windex) ;
  journal_end(&th, dir->i_sb, jbegin_count) ;
  return 0;
}
コード例 #17
0
ファイル: namei.c プロジェクト: chinnyannieb/empeg-hijack
int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev)
{
  int error;
  struct inode * inode;
  struct path path_to_entry;
  struct reiserfs_dir_entry de;
  int windex ;
  struct reiserfs_transaction_handle th ;
  int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 
  int err;

  if (!dir)
    return -ENOENT;

  init_path (&path_to_entry);

  inode = get_empty_inode() ;
  if (!inode) {
    return -ENOSPC ;
  }
  journal_begin(&th, dir->i_sb, jbegin_count) ;
  windex = push_journal_writer("reiserfs_mknod") ;
  de.de_gen_number_bit_string = 0;
  if (reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path_to_entry, &de) == POSITION_FOUND) {
    pathrelse ( &path_to_entry);
    pop_journal_writer(windex) ;
    journal_end(&th, dir->i_sb, jbegin_count) ;
    iput(inode) ;
    return -EEXIST;
  }

  pathrelse ( &path_to_entry);

  inode = reiserfs_new_inode (&th, dir, mode, 0, dentry, inode, &err);
  if (!inode) {
    pop_journal_writer(windex) ;
    journal_end(&th, dir->i_sb, jbegin_count) ;
    return err;
  }
  reiserfs_update_inode_transaction(inode) ;
  reiserfs_update_inode_transaction(dir) ;

  inode->i_uid = current->fsuid;
  inode->i_mode = mode;
  inode->i_op = NULL;

  if (S_ISREG(inode->i_mode))
    inode->i_op = &reiserfs_file_inode_operations;
  else if (S_ISDIR(inode->i_mode)) {
    inode->i_op = &reiserfs_dir_inode_operations;
    if (dir->i_mode & S_ISGID)
      inode->i_mode |= S_ISGID;
  }
  else if (S_ISLNK(inode->i_mode))
    inode->i_op = &reiserfs_symlink_inode_operations;
  else if (S_ISCHR(inode->i_mode))
    inode->i_op = &chrdev_inode_operations;
  else if (S_ISBLK(inode->i_mode))
    inode->i_op = &blkdev_inode_operations;
  else if (S_ISFIFO(inode->i_mode))
    init_fifo(inode);
  if (S_ISBLK(mode) || S_ISCHR(mode))
    inode->i_rdev = to_kdev_t(rdev);

  if_in_ram_update_sd (&th, inode);

  error = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, INODE_PKEY (inode), &de, 1);
  if (error) {
    inode->i_nlink--;
    if_in_ram_update_sd (&th, inode);
    pop_journal_writer(windex) ;
    journal_end(&th, dir->i_sb, jbegin_count) ;
    iput (inode);
    return error;
  }
  if_in_ram_update_sd (&th, dir);
  d_instantiate(dentry, inode);
  pop_journal_writer(windex) ;
  journal_end(&th, dir->i_sb, jbegin_count) ;
  return 0;
}
コード例 #18
0
ファイル: super.c プロジェクト: chinnyannieb/empeg-hijack
void __init mount_root(void)
{
	struct file_system_type * fs_type;
	struct super_block * sb;
	struct vfsmount *vfsmnt;
	struct inode * d_inode = NULL;
	struct file filp;
	int retval;

#ifdef CONFIG_ROOT_NFS
	if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
		ROOT_DEV = 0;
		if ((fs_type = get_fs_type("nfs"))) {
			sb = get_empty_super(); /* "can't fail" */
			sb->s_dev = get_unnamed_dev();
			sb->s_flags = root_mountflags;
			sema_init(&sb->s_vfs_rename_sem,1);
			vfsmnt = add_vfsmnt(sb, "/dev/root", "/");
			if (vfsmnt) {
				if (nfs_root_mount(sb) >= 0) {
					sb->s_dirt = 0;
					sb->s_type = fs_type;
					current->fs->root = dget(sb->s_root);
					current->fs->pwd = dget(sb->s_root);
					ROOT_DEV = sb->s_dev;
			                printk (KERN_NOTICE "VFS: Mounted root (NFS filesystem)%s.\n", (sb->s_flags & MS_RDONLY) ? " readonly" : "");
					return;
				}
				remove_vfsmnt(sb->s_dev);
			}
			put_unnamed_dev(sb->s_dev);
			sb->s_dev = 0;
		}
		if (!ROOT_DEV) {
			printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
			ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
		}
	}
#endif

#ifdef CONFIG_BLK_DEV_FD
	if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
#ifdef CONFIG_BLK_DEV_RAM	
		extern int rd_doload;
#endif		
		floppy_eject();
#ifndef CONFIG_BLK_DEV_RAM
		printk(KERN_NOTICE "(Warning, this kernel has no ramdisk support)\n");
#else
		/* rd_doload is 2 for a dual initrd/ramload setup */
		if(rd_doload==2)
			rd_load_secondary();
		else
#endif		
		{
			printk(KERN_NOTICE "VFS: Insert root floppy and press ENTER\n");
			wait_for_keypress();
		}
	}
#endif

	memset(&filp, 0, sizeof(filp));
	d_inode = get_empty_inode();
	d_inode->i_rdev = ROOT_DEV;
	filp.f_dentry = NULL;
	if ( root_mountflags & MS_RDONLY)
		filp.f_mode = 1; /* read only */
	else
		filp.f_mode = 3; /* read write */
	retval = blkdev_open(d_inode, &filp);
	if (retval == -EROFS) {
		root_mountflags |= MS_RDONLY;
		filp.f_mode = 1;
		retval = blkdev_open(d_inode, &filp);
	}
	iput(d_inode);
	if (retval)
	        /*
		 * Allow the user to distinguish between failed open
		 * and bad superblock on root device.
		 */
		printk("VFS: Cannot open root device %s\n",
		       kdevname(ROOT_DEV));
	else for (fs_type = file_systems ; fs_type ; fs_type = fs_type->next) {
  		if (!(fs_type->fs_flags & FS_REQUIRES_DEV))
  			continue;
  		sb = read_super(ROOT_DEV,fs_type->name,root_mountflags,root_mount_data,1);
		if (sb) {
			sb->s_flags = root_mountflags;
			current->fs->root = dget(sb->s_root);
			current->fs->pwd = dget(sb->s_root);
			printk ("VFS: Mounted root (%s filesystem)%s.\n",
				fs_type->name,
				(sb->s_flags & MS_RDONLY) ? " readonly" : "");
			vfsmnt = add_vfsmnt(sb, "/dev/root", "/");
			if (vfsmnt)
				return;
			panic("VFS: add_vfsmnt failed for root fs");
		}
	}
#ifdef CONFIG_EMPEG_DISPLAY
	display_bootfail();
#endif
	panic("VFS: Unable to mount root fs on %s",
		kdevname(ROOT_DEV));
}
コード例 #19
0
/*
 * There are two policies for allocating an inode.  If the new inode is
 * a directory, then a forward search is made for a block group with both
 * free space and a low directory-to-inode ratio; if that fails, then of
 * the groups with above-average free space, that group with the fewest
 * directories already is chosen.
 *
 * For other inodes, search forward from the parent directory\'s block
 * group to find a free inode.
 */
struct inode * ext2_new_inode (const struct inode * dir, int mode, int * err)
{
	struct super_block * sb;
	struct buffer_head * bh;
	struct buffer_head * bh2;
	int i, j, avefreei;
	struct inode * inode;
	int bitmap_nr;
	struct ext2_group_desc * gdp;
	struct ext2_group_desc * tmp;
	struct ext2_super_block * es;

	/* Cannot create files in a deleted directory */
	if (!dir || !dir->i_nlink) {
		*err = -EPERM;
		return NULL;
	}

	inode = get_empty_inode ();
	if (!inode) {
		*err = -ENOMEM;
		return NULL;
	}

	sb = dir->i_sb;
	inode->i_sb = sb;
	inode->i_flags = 0;
	lock_super (sb);
	es = sb->u.ext2_sb.s_es;
repeat:
	gdp = NULL; i=0;
	
	*err = -ENOSPC;
	if (S_ISDIR(mode)) {
		avefreei = le32_to_cpu(es->s_free_inodes_count) /
			sb->u.ext2_sb.s_groups_count;
/* I am not yet convinced that this next bit is necessary.
		i = dir->u.ext2_i.i_block_group;
		for (j = 0; j < sb->u.ext2_sb.s_groups_count; j++) {
			tmp = ext2_get_group_desc (sb, i, &bh2);
			if (tmp &&
			    (le16_to_cpu(tmp->bg_used_dirs_count) << 8) < 
			     le16_to_cpu(tmp->bg_free_inodes_count)) {
				gdp = tmp;
				break;
			}
			else
			i = ++i % sb->u.ext2_sb.s_groups_count;
		}
*/
		if (!gdp) {
			for (j = 0; j < sb->u.ext2_sb.s_groups_count; j++) {
				tmp = ext2_get_group_desc (sb, j, &bh2);
				if (tmp &&
				    le16_to_cpu(tmp->bg_free_inodes_count) &&
				    le16_to_cpu(tmp->bg_free_inodes_count) >= avefreei) {
					if (!gdp || 
					    (le16_to_cpu(tmp->bg_free_blocks_count) >
					     le16_to_cpu(gdp->bg_free_blocks_count))) {
						i = j;
						gdp = tmp;
					}
				}
			}
		}
	}
	else 
	{
		/*
		 * Try to place the inode in its parent directory
		 */
		i = dir->u.ext2_i.i_block_group;
		tmp = ext2_get_group_desc (sb, i, &bh2);
		if (tmp && le16_to_cpu(tmp->bg_free_inodes_count))
			gdp = tmp;
		else
		{
			/*
			 * Use a quadratic hash to find a group with a
			 * free inode
			 */
			for (j = 1; j < sb->u.ext2_sb.s_groups_count; j <<= 1) {
				i += j;
				if (i >= sb->u.ext2_sb.s_groups_count)
					i -= sb->u.ext2_sb.s_groups_count;
				tmp = ext2_get_group_desc (sb, i, &bh2);
				if (tmp &&
				    le16_to_cpu(tmp->bg_free_inodes_count)) {
					gdp = tmp;
					break;
				}
			}
		}
		if (!gdp) {
			/*
			 * That failed: try linear search for a free inode
			 */
			i = dir->u.ext2_i.i_block_group + 1;
			for (j = 2; j < sb->u.ext2_sb.s_groups_count; j++) {
				if (++i >= sb->u.ext2_sb.s_groups_count)
					i = 0;
				tmp = ext2_get_group_desc (sb, i, &bh2);
				if (tmp &&
				    le16_to_cpu(tmp->bg_free_inodes_count)) {
					gdp = tmp;
					break;
				}
			}
		}
	}

	if (!gdp) {
		unlock_super (sb);
		iput(inode);
		return NULL;
	}
	bitmap_nr = load_inode_bitmap (sb, i);
	if (bitmap_nr < 0) {
		unlock_super (sb);
		iput(inode);
		*err = -EIO;
		return NULL;
	}

	bh = sb->u.ext2_sb.s_inode_bitmap[bitmap_nr];
	if ((j = ext2_find_first_zero_bit ((unsigned long *) bh->b_data,
				      EXT2_INODES_PER_GROUP(sb))) <
	    EXT2_INODES_PER_GROUP(sb)) {
		if (ext2_set_bit (j, bh->b_data)) {
			ext2_warning (sb, "ext2_new_inode",
				      "bit already set for inode %d", j);
			goto repeat;
		}
		mark_buffer_dirty(bh, 1);
		if (sb->s_flags & MS_SYNCHRONOUS) {
			ll_rw_block (WRITE, 1, &bh);
			wait_on_buffer (bh);
		}
	} else {
		if (le16_to_cpu(gdp->bg_free_inodes_count) != 0) {
			ext2_error (sb, "ext2_new_inode",
				    "Free inodes count corrupted in group %d",
				    i);
			unlock_super (sb);
			iput (inode);
			return NULL;
		}
		goto repeat;
	}
	j += i * EXT2_INODES_PER_GROUP(sb) + 1;
	if (j < EXT2_FIRST_INO(sb) || j > le32_to_cpu(es->s_inodes_count)) {
		ext2_error (sb, "ext2_new_inode",
			    "reserved inode or inode > inodes count - "
			    "block_group = %d,inode=%d", i, j);
		unlock_super (sb);
		iput (inode);
		return NULL;
	}
	gdp->bg_free_inodes_count =
		cpu_to_le16(le16_to_cpu(gdp->bg_free_inodes_count) - 1);
	if (S_ISDIR(mode))
		gdp->bg_used_dirs_count =
			cpu_to_le16(le16_to_cpu(gdp->bg_used_dirs_count) + 1);
	mark_buffer_dirty(bh2, 1);
	es->s_free_inodes_count =
		cpu_to_le32(le32_to_cpu(es->s_free_inodes_count) - 1);
	mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1);
	sb->s_dirt = 1;
	inode->i_mode = mode;
	inode->i_sb = sb;
	inode->i_nlink = 1;
	inode->i_dev = sb->s_dev;
	inode->i_uid = current->fsuid;
	if (test_opt (sb, GRPID))
		inode->i_gid = dir->i_gid;
	else if (dir->i_mode & S_ISGID) {
		inode->i_gid = dir->i_gid;
		if (S_ISDIR(mode))
			mode |= S_ISGID;
	} else
		inode->i_gid = current->fsgid;

	inode->i_ino = j;
	inode->i_blksize = PAGE_SIZE;	/* This is the optimal IO size (for stat), not the fs block size */
	inode->i_blocks = 0;
	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
	inode->u.ext2_i.i_new_inode = 1;
	inode->u.ext2_i.i_flags = dir->u.ext2_i.i_flags;
	if (S_ISLNK(mode))
		inode->u.ext2_i.i_flags &= ~(EXT2_IMMUTABLE_FL | EXT2_APPEND_FL);
	inode->u.ext2_i.i_faddr = 0;
	inode->u.ext2_i.i_frag_no = 0;
	inode->u.ext2_i.i_frag_size = 0;
	inode->u.ext2_i.i_file_acl = 0;
	inode->u.ext2_i.i_dir_acl = 0;
	inode->u.ext2_i.i_dtime = 0;
	inode->u.ext2_i.i_block_group = i;
	inode->i_op = NULL;
	if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL)
		inode->i_flags |= MS_SYNCHRONOUS;
	insert_inode_hash(inode);
	mark_inode_dirty(inode);
	inc_inode_version (inode, gdp, mode);

	unlock_super (sb);
	if(DQUOT_ALLOC_INODE(sb, inode)) {
		sb->dq_op->drop(inode);
		inode->i_nlink = 0;
		iput(inode);
		*err = -EDQUOT;
		return NULL;
	}
	ext2_debug ("allocating inode %lu\n", inode->i_ino);

	*err = 0;
	return inode;
}
コード例 #20
0
ファイル: fs.c プロジェクト: chinnyannieb/empeg-hijack
static int
ntfs_create(struct inode* dir,struct dentry *d,int mode)
{
	struct inode *r=0;
	ntfs_inode *ino=0;
	ntfs_volume *vol;
	int error=0;
	ntfs_attribute *si;

	r=get_empty_inode();
	if(!r){
		error=ENOMEM;
		goto fail;
	}

	ntfs_debug(DEBUG_OTHER, "ntfs_create %s\n",d->d_name.name);
	vol=NTFS_INO2VOL(dir);
#ifdef NTFS_IN_LINUX_KERNEL
	ino=NTFS_LINO2NINO(r);
#else
	ino=ntfs_malloc(sizeof(ntfs_inode));
	if(!ino){
		error=ENOMEM;
		goto fail;
	}
	r->u.generic_ip=ino;
#endif
	error=ntfs_alloc_file(NTFS_LINO2NINO(dir),ino,(char*)d->d_name.name,
			       d->d_name.len);
	if(error)goto fail;
	error=ntfs_update_inode(ino);
	if(error)goto fail;
	error=ntfs_update_inode(NTFS_LINO2NINO(dir));
	if(error)goto fail;

	r->i_uid=vol->uid;
	r->i_gid=vol->gid;
	r->i_nlink=1;
	r->i_sb=dir->i_sb;
	/* FIXME: dirty? dev? */
	/* get the file modification times from the standard information */
	si=ntfs_find_attr(ino,vol->at_standard_information,NULL);
	if(si){
		char *attr=si->d.data;
		r->i_atime=ntfs_ntutc2unixutc(NTFS_GETU64(attr+0x18));
		r->i_ctime=ntfs_ntutc2unixutc(NTFS_GETU64(attr));
		r->i_mtime=ntfs_ntutc2unixutc(NTFS_GETU64(attr+8));
	}
	/* It's not a directory */
	r->i_op=&ntfs_inode_operations_nobmap;
	r->i_mode=S_IFREG|S_IRUGO;
#ifdef CONFIG_NTFS_RW
	r->i_mode|=S_IWUGO;
#endif
	r->i_mode &= ~vol->umask;

	insert_inode_hash(r);
	d_instantiate(d,r);
	return 0;
 fail:
	#ifndef NTFS_IN_LINUX_KERNEL
	if(ino)ntfs_free(ino);
	#endif
	if(r)iput(r);
	return -error;
}