📄 fs_incore.c
字号:
return 0;}static int_sysio_incore_dirop_mkdir(struct pnode *pno, mode_t mode){ struct intnl_stat stat; struct incore_inode *icino, *parent; ino_t inum; int err; struct intnl_dirent *de = NULL; struct inode *ino; ino = pno->p_parent->p_base->pb_ino; parent = I2IC(ino); if (!S_ISDIR(parent->ici_st.st_mode)) return -ENOTDIR; (void )memset(&stat, 0, sizeof(stat)); stat.st_dev = pno->p_parent->p_base->pb_ino->i_fs->fs_dev; inum = incore_inum_alloc();#ifdef HAVE__ST_INO stat.__st_ino = inum;#endif stat.st_mode = S_IFDIR | (mode & 07777); stat.st_nlink = 2; stat.st_uid = getuid(); stat.st_gid = getgid(); stat.st_size = 0; stat.st_blksize = 4096; stat.st_blocks = 0; stat.st_ctime = stat.st_mtime = stat.st_atime = 0; stat.st_ino = inum; icino = incore_directory_new(FS2ICFS(ino->i_fs), parent, &stat); if (!icino) return -ENOSPC; /* * Tell the system about the new inode. * * Persistent across remounts because we ask for immunity. */ ino = _sysio_i_new(pno->p_parent->p_base->pb_ino->i_fs, &icino->ici_fileid, &stat, 1, &_sysio_incore_dir_ops, icino); if (!ino) { incore_i_destroy(icino); return -ENOMEM; } /* * Insert into parent. */ err = incore_directory_insert(parent, &pno->p_base->pb_name, stat.st_ino, INCORE_D_TYPEOF(S_IFDIR)); if (err) { de->d_ino = 0; /* bad parent */ I_RELE(ino); _sysio_i_gone(ino); return err; } pno->p_base->pb_ino = ino; return 0;}static intincore_unlink_entry(struct incore_inode *icino, struct qstr *name){ struct lookup_data lookup_data; struct intnl_dirent *de; size_t reclen;#ifdef _DIRENT_HAVE_D_OFF size_t off;#endif if (!S_ISDIR(icino->ici_st.st_mode)) return -ENOTDIR; INCORE_LD_INIT(&lookup_data, 0, name); de = incore_directory_probe(icino->ici_data, icino->ici_st.st_size, 0, (probe_ty )incore_directory_match, NULL, &lookup_data); if (!de) return -ENOENT; assert((size_t )((char *)de - (char *)icino->ici_data) >= sizeof(incore_dir_template));#ifndef _DIRENT_HAVE_D_OFF reclen = de->d_reclen;#else off = de->d_off; reclen = off - ((char *)de - (char *)icino->ici_data);#endif (void )memset(de, 0, reclen);#ifndef _DIRENT_HAVE_D_OFF de->d_type = (__uint8_t )DTTOIF(DT_WHT); de->d_reclen = reclen;#else lookup_data.de->d_off = off;#endif /* * Adjust link count. */ assert(icino->ici_st.st_nlink > 2); icino->ici_st.st_nlink--; return 0;}static int_sysio_incore_dirop_rmdir(struct pnode *pno){ struct inode *ino = pno->p_base->pb_ino; struct incore_inode *icino = I2IC(ino); int err; if (!pno->p_base->pb_name.len || (pno->p_base->pb_name.name[0] == '.' && (pno->p_base->pb_name.len == 1 || (pno->p_base->pb_name.len == 2 && pno->p_base->pb_name.name[1] == '.')))) return -EINVAL; if (!S_ISDIR(icino->ici_st.st_mode)) return -ENOTDIR; if (icino->ici_st.st_nlink > 2) return -ENOTEMPTY; pno->p_base->pb_ino = NULL; err = incore_unlink_entry(I2IC(pno->p_parent->p_base->pb_ino), &pno->p_base->pb_name); return err;}static intincore_create(struct pnode *pno, struct intnl_stat *stat){ struct inode *dino, *ino; struct incore_inode *icino; int err; dino = pno->p_parent->p_base->pb_ino; assert(dino); icino = incore_i_alloc(FS2ICFS(dino->i_fs), stat); if (!icino) return -ENOSPC; /* * Tell the system about the new inode. */ ino = _sysio_i_new(dino->i_fs, &icino->ici_fileid, stat, 1, S_ISREG(stat->st_mode) ? &_sysio_incore_file_ops : &_sysio_incore_dev_ops, icino); if (!ino) { incore_i_destroy(icino); return -ENOMEM; } /* * Insert into parent. */ err = incore_directory_insert(I2IC(dino), &pno->p_base->pb_name, stat->st_ino, INCORE_D_TYPEOF(icino->ici_st.st_mode)); if (err) { I_RELE(ino); _sysio_i_gone(ino); return err; } pno->p_base->pb_ino = ino; return 0;}static int_sysio_incore_inop_open(struct pnode *pno, int flags __IS_UNUSED, mode_t mode){ struct intnl_stat stat; ino_t inum; /* * File exists. Nothing to do. */ if (pno->p_base->pb_ino) return 0; /* * Must create a new, regular, file. */ (void )memset(&stat, 0, sizeof(stat)); stat.st_dev = pno->p_parent->p_base->pb_ino->i_fs->fs_dev; inum = incore_inum_alloc();#ifdef HAVE__ST_INO stat.__st_ino = inum;#endif stat.st_mode = S_IFREG | (mode & 07777); stat.st_nlink = 1; stat.st_uid = getuid(); stat.st_gid = getgid(); stat.st_rdev = 0; stat.st_size = 0; stat.st_blksize = 4096; stat.st_blocks = 0; stat.st_ctime = stat.st_mtime = stat.st_atime = 0; stat.st_ino = inum; return incore_create(pno, &stat);}static int_sysio_incore_inop_close(struct inode *ino __IS_UNUSED){ return 0;}static int_sysio_incore_dirop_link(struct pnode *old, struct pnode *new){ struct incore_inode *icino = I2IC(old->p_base->pb_ino); int err; assert(!new->p_base->pb_ino); assert(!S_ISDIR(old->p_base->pb_ino->i_stbuf.st_mode)); /* * Can bump the link count? */ if (!(icino->ici_st.st_nlink + 1)) return -EMLINK; /* * Insert into parent. */ err = incore_directory_insert(I2IC(new->p_parent->p_base->pb_ino), &new->p_base->pb_name, icino->ici_st.st_ino, INCORE_D_TYPEOF(icino->ici_st.st_mode)); if (err) return err; /* * Bump the link count. */ icino->ici_st.st_nlink++; return 0;}static int_sysio_incore_dirop_rename(struct pnode *old, struct pnode *new){ int err; struct incore_inode *icino = I2IC(old->p_base->pb_ino); if (new->p_base->pb_ino) { /* * Have to kill off the target first. */ if (S_ISDIR(I2IC(new->p_base->pb_ino)->ici_st.st_mode) && I2IC(new->p_base->pb_ino)->ici_st.st_nlink > 2) return -ENOTEMPTY; err = incore_unlink_entry(I2IC(new->p_parent->p_base->pb_ino), &new->p_base->pb_name); if (err) return err; } /* * Insert into new parent. */ err = incore_directory_insert(I2IC(new->p_parent->p_base->pb_ino), &new->p_base->pb_name, icino->ici_st.st_ino, INCORE_D_TYPEOF(icino->ici_st.st_mode)); if (err) abort(); /* * Remove from the old parent. */ err = incore_unlink_entry(I2IC(old->p_parent->p_base->pb_ino), &old->p_base->pb_name); if (err) abort(); if (S_ISDIR(icino->ici_st.st_mode)) { struct intnl_dirent *de; /* * We moved a directory. The entry for `..' must be corrected. */ de = icino->ici_data; de++; assert(strcmp(de->d_name, "..") == 0); de->d_ino = I2IC(new->p_parent->p_base->pb_ino)->ici_st.st_ino; } return 0;}static int_sysio_incore_dirop_unlink(struct pnode *pno){ struct inode *ino = pno->p_base->pb_ino; struct incore_inode *icino = I2IC(ino); int err; if (S_ISDIR(icino->ici_st.st_mode)) return -EISDIR; err = incore_unlink_entry(I2IC(pno->p_parent->p_base->pb_ino), &pno->p_base->pb_name); return err;}static intdoio(ssize_t (*f)(void *, size_t, _SYSIO_OFF_T, struct incore_inode *), struct inode *ino, struct ioctx *ioctx){ ioctx->ioctx_cc = _sysio_doio(ioctx->ioctx_xtv, ioctx->ioctx_xtvlen, ioctx->ioctx_iov, ioctx->ioctx_iovlen, (ssize_t (*)(void *, size_t, _SYSIO_OFF_T, void *))f, I2IC(ino)); if (ioctx->ioctx_cc < 0) { ioctx->ioctx_errno = -ioctx->ioctx_cc; ioctx->ioctx_cc = -1; } ioctx->ioctx_done = 1; return 0;}static ssize_tincore_read(void *buf, size_t nbytes, _SYSIO_OFF_T off, struct incore_inode *icino){ size_t n; if (off < 0) return -EINVAL; if (!nbytes || off > icino->ici_st.st_size) return 0; n = icino->ici_st.st_size - (size_t )off; if (n > nbytes) n = nbytes; (void )memcpy(buf, (char *)icino->ici_data + off, (size_t )n); return (ssize_t )n;}static int_sysio_incore_filop_read(struct inode *ino, struct ioctx *ioctx){ return doio(incore_read, ino, ioctx);}static ssize_tincore_write(const void *buf, size_t nbytes, _SYSIO_OFF_T off, struct incore_inode *icino){ _SYSIO_OFF_T pos; if (off < 0) return -EINVAL; if (!nbytes || off > icino->ici_st.st_size) return 0; pos = off + nbytes; if (off && pos <= off) { /* * It's all or nothing. We won't write just part of * the buffer. */ return -EFBIG; } if (pos > icino->ici_st.st_size) { int err; err = incore_trunc(icino, (size_t )pos, 0); if (err) return err; } (void )memcpy((char *)icino->ici_data + off, buf, nbytes); return (ssize_t )nbytes;}static int_sysio_incore_filop_write(struct inode *ino, struct ioctx *ioctx){ return doio((ssize_t (*)(void *, size_t, _SYSIO_OFF_T, struct incore_inode *))incore_write, ino, ioctx);}static _SYSIO_OFF_T_sysio_incore_filop_pos(struct inode *ino __IS_UNUSED, _SYSIO_OFF_T off){ return off;}static int_sysio_incore_filop_iodone(struct ioctx *iocp __IS_UNUSED){ /* * It's always done in this driver. It completed when posted. */ return 1;}static int_sysio_incore_filop_fcntl(struct inode *ino __IS_UNUSED, int cmd __IS_UNUSED, va_list ap __IS_UNUSED, int *rtn){ /* * No fcntl's supported. */ *rtn = -1; return -ENOTTY;}static int_sysio_incore_inop_sync(struct inode *ino __IS_UNUSED){ /* * With what? */ return 0;}static int_sysio_incore_filop_ioctl(struct inode *ino __IS_UNUSED, unsigned long int request __IS_UNUSED, va_list ap __IS_UNUSED){ /* * No ioctl's supported. */ return -ENOTTY;}static int_sysio_incore_dirop_mknod(struct pnode *pno, mode_t mode, dev_t dev){ mode_t m; struct intnl_stat stat; ino_t inum; assert(!pno->p_base->pb_ino); m = mode & S_IFMT; if (S_ISCHR(m)) m &= ~S_IFCHR; else if (S_ISFIFO(m)) m &= ~S_IFIFO; else if (S_ISBLK(m)) m &= ~S_IFCHR; else return -EINVAL; if (m) return -EINVAL; /* * Initialize attributes. */ (void )memset(&stat, 0, sizeof(stat)); stat.st_dev = pno->p_parent->p_base->pb_ino->i_fs->fs_dev; inum = incore_inum_alloc();#ifdef HAVE__ST_INO stat.__st_ino = inum;#endif stat.st_mode = mode; stat.st_nlink = 1; stat.st_uid = getuid(); stat.st_gid = getgid(); stat.st_rdev = dev; stat.st_size = 0; stat.st_blksize = 4096; stat.st_blocks = 0; stat.st_ctime = stat.st_mtime = stat.st_atime = 0; stat.st_ino = inum; return incore_create(pno, &stat);}#ifdef _HAVE_STATVFSstatic int_sysio_incore_inop_statvfs(struct pnode *pno, struct inode *ino, struct intnl_statvfs *buf){ struct filesys *fs; if (!ino) ino = pno->p_base->pb_ino; assert(ino); fs = pno->p_base->pb_ino->i_fs; (void )memset(buf, 0, sizeof(struct intnl_statvfs)); /* * Mostly, we lie. */ buf->f_bsize = fs->fs_bsize; buf->f_frsize = buf->f_bsize; buf->f_blocks = ~0; buf->f_blocks /= buf->f_bsize; buf->f_bfree = buf->f_blocks - 1; buf->f_bavail = buf->f_bfree; buf->f_files = buf->f_blocks; buf->f_ffree = buf->f_files - 1; buf->f_favail = buf->f_ffree; buf->f_fsid = fs->fs_id; buf->f_flag = 0; buf->f_namemax = ULONG_MAX; return 0;}#endifvoid_sysio_incore_inop_gone(struct inode *ino){ struct incore_inode *icino = I2IC(ino); incore_i_destroy(icino);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -