int op_unlink (const char *path) { int rt; errcode_t rc; char *p_path; char *r_path; ext2_ino_t p_ino; struct ext2_inode p_inode; ext2_ino_t r_ino; struct ext2_vnode *r_vnode; struct ext2_inode *r_inode; ext2_filsys e2fs; FUSE_EXT2_LOCK; e2fs = current_ext2fs(); debugf("enter"); debugf("path = %s", path); rt=do_check_split(path, &p_path, &r_path); if (rt != 0) { debugf("do_check_split: failed"); goto err; } debugf("parent: %s, child: %s", p_path, r_path); rt = do_readinode(e2fs, p_path, &p_ino, &p_inode); if (rt) { debugf("do_readinode(%s, &p_ino, &p_inode); failed", p_path); goto err_free_split; } rt = do_readvnode(e2fs, path, &r_ino, &r_vnode, DONT_OPEN_FILE); if (rt) { debugf("do_readvnode(%s, &r_ino, &r_vnode); failed", path); goto err_free_split; } r_inode = vnode2inode(r_vnode); if(LINUX_S_ISDIR(r_inode->i_mode)) { debugf("%s is a directory", path); vnode_put(r_vnode,0); rt = -EISDIR; goto err_free_split; } rc = ext2fs_unlink(e2fs, p_ino, r_path, r_ino, 0); if (rc) { debugf("ext2fs_unlink(e2fs, %d, %s, %d, 0); failed", p_ino, r_path, r_ino); vnode_put(r_vnode,0); rt = -EIO; goto err_free_split; } if (r_inode->i_links_count > 0) { r_inode->i_links_count -= 1; } p_inode.i_ctime = p_inode.i_mtime = e2fs->now ? e2fs->now : time(NULL); rc = ext2fs_write_inode(e2fs, p_ino, &p_inode); if (rc) { debugf("ext2fs_write_inode(e2fs, p_ino, &p_inode); failed"); vnode_put(r_vnode,1); rt = -EIO; goto err_free_split; } r_inode->i_ctime = e2fs->now ? e2fs->now : time(NULL); rc = vnode_put(r_vnode,1); if (rc) { debugf("vnode_put(r_vnode,1); failed"); rt = -EIO; goto err_free_split; } free_split(p_path, r_path); debugf("leave"); FUSE_EXT2_UNLOCK; return 0; err_free_split: free_split(p_path, r_path); err: FUSE_EXT2_UNLOCK; return rt; }
int op_mkdir (const char *path, mode_t mode) { int rt; time_t tm; char *p_path; char *r_path; ino_t ino; struct ufs_vnode *vnode; struct ufs_vnode *child_vnode; struct inode *inode; struct fuse_context *ctx; uufsd_t *ufs = current_ufs(); RETURN_IF_RDONLY(ufs); debugf("enter"); debugf("path = %s, mode: 0%o, dir:0%o", path, mode, S_IFDIR); rt=do_check_split(path, &p_path ,&r_path); if (rt != 0) { debugf("do_check(%s); failed", path); return rt; } debugf("parent: %s, child: %s, pathmax: %d", p_path, r_path, PATH_MAX); rt = do_readvnode(ufs, p_path, &ino, &vnode); if (!vnode) { debugf("do_readvnode(%s, &ino, &vnode); failed", p_path); free_split(p_path, r_path); return rt; } debugf("calling ufs_mkdir(ufs, %d, 0, %s);", ino, r_path); rt = ufs_mkdir(ufs, ino, 0, r_path); if (rt) { debugf("ufs_mkdir(ufs, %d, 0, %s); failed (%d)", ino, r_path, rt); free_split(p_path, r_path); return rt; } rt = do_readvnode(ufs, path, &ino, &child_vnode); if (rt) { debugf("do_readvnode(%s, &ino, &child_vnode); failed", path); return -EIO; } tm = ufs->now ? ufs->now : time(NULL); inode = vnode2inode(child_vnode); inode->i_mode = S_IFDIR | mode; inode->i_ctime = inode->i_atime = inode->i_mtime = tm; ctx = fuse_get_context(); if (ctx) { inode->i_uid = ctx->uid; inode->i_gid = ctx->gid; } vnode_put(child_vnode, 1); inode = vnode2inode(vnode); inode->i_ctime = inode->i_mtime = tm; vnode_put(vnode, 1); free_split(p_path, r_path); debugf("leave"); return 0; }
int do_create (ext2_filsys e2fs, const char *path, mode_t mode, dev_t dev, const char *fastsymlink) { int rt; time_t tm; errcode_t rc; char *p_path; char *r_path; ext2_ino_t ino; struct ext2_inode inode; ext2_ino_t n_ino; struct fuse_context *ctx; debugf("enter"); debugf("path = %s, mode: 0%o", path, mode); rt=do_check_split(path, &p_path, &r_path); debugf("parent: %s, child: %s", p_path, r_path); rt = do_readinode(e2fs, p_path, &ino, &inode); if (rt) { debugf("do_readinode(%s, &ino, &inode); failed", p_path); free_split(p_path, r_path); return rt; } rc = ext2fs_new_inode(e2fs, ino, mode, 0, &n_ino); if (rc) { debugf("ext2fs_new_inode(ep.fs, ino, mode, 0, &n_ino); failed"); return -ENOMEM; } do { debugf("calling ext2fs_link(e2fs, %d, %s, %d, %d);", ino, r_path, n_ino, do_modetoext2lag(mode)); rc = ext2fs_link(e2fs, ino, r_path, n_ino, do_modetoext2lag(mode)); if (rc == EXT2_ET_DIR_NO_SPACE) { debugf("calling ext2fs_expand_dir(e2fs, &d)", ino); if (ext2fs_expand_dir(e2fs, ino)) { debugf("error while expanding directory %s (%d)", p_path, ino); free_split(p_path, r_path); return -ENOSPC; } } } while (rc == EXT2_ET_DIR_NO_SPACE); if (rc) { debugf("ext2fs_link(e2fs, %d, %s, %d, %d); failed", ino, r_path, n_ino, do_modetoext2lag(mode)); free_split(p_path, r_path); return -EIO; } if (ext2fs_test_inode_bitmap(e2fs->inode_map, n_ino)) { debugf("inode already set"); } ext2fs_inode_alloc_stats2(e2fs, n_ino, +1, 0); memset(&inode, 0, sizeof(inode)); tm = e2fs->now ? e2fs->now : time(NULL); inode.i_mode = mode; inode.i_atime = inode.i_ctime = inode.i_mtime = tm; inode.i_links_count = 1; inode.i_size = 0; ctx = fuse_get_context(); if (ctx) { inode.i_uid = ctx->uid; inode.i_gid = ctx->gid; } if (S_ISCHR(mode) || S_ISBLK(mode)) { if (old_valid_dev(dev)) inode.i_block[0]= ext2fs_cpu_to_le32(old_encode_dev(dev)); else inode.i_block[1]= ext2fs_cpu_to_le32(new_encode_dev(dev)); } if (S_ISLNK(mode) && fastsymlink != NULL) { inode.i_size = strlen(fastsymlink); strncpy((char *)&(inode.i_block[0]),fastsymlink, (EXT2_N_BLOCKS * sizeof(inode.i_block[0]))); } rc = ext2fs_write_new_inode(e2fs, n_ino, &inode); if (rc) { debugf("ext2fs_write_new_inode(e2fs, n_ino, &inode);"); free_split(p_path, r_path); return -EIO; } /* update parent dir */ rt = do_readinode(e2fs, p_path, &ino, &inode); if (rt) { debugf("do_readinode(%s, &ino, &inode); dailed", p_path); free_split(p_path, r_path); return -EIO; } inode.i_ctime = inode.i_mtime = tm; rc = ext2fs_write_inode(e2fs, ino, &inode); if (rc) { debugf("ext2fs_write_inode(e2fs, ino, &inode); failed"); free_split(p_path, r_path); return -EIO; } free_split(p_path, r_path); debugf("leave"); return 0; }
int op_link (const char *source, const char *dest) { int rc; char *p_path; char *r_path; ino_t d_ino, ino; struct ufs_vnode *vnode; struct inode *inode; uufsd_t *ufs = current_ufs(); RETURN_IF_RDONLY(ufs); debugf("source: %s, dest: %s", source, dest); rc = do_check(source); if (rc != 0) { debugf("do_check(%s); failed", source); return rc; } rc = do_check_split(dest, &p_path, &r_path); if (rc != 0) { debugf("do_check(%s); failed", dest); return rc; } debugf("parent: %s, child: %s", p_path, r_path); rc = do_readvnode(ufs, p_path, &d_ino, &vnode); if (rc) { debugf("do_readvnode(%s, &d_ino, &inode); failed", p_path); free_split(p_path, r_path); return rc; } vnode_put(vnode, 0); rc = do_readvnode(ufs, source, &ino, &vnode); if (rc) { debugf("do_readvnode(%s, &d_ino, &inode); failed", source); free_split(p_path, r_path); return rc; } inode = vnode2inode(vnode); rc = ufs_link(ufs, d_ino, r_path, vnode, inode->i_mode); if (rc) { debugf("ufs_link() failed"); vnode_put(vnode, 0); free_split(p_path, r_path); return rc; } inode->i_mtime = inode->i_atime = inode->i_ctime = ufs->now ? ufs->now : time(NULL); rc = vnode_put(vnode, 1); if (rc) { debugf("vnode_put(vnode,1); failed"); free_split(p_path, r_path); return -EIO; } debugf("done"); return 0; }
int op_link (const char *source, const char *dest) { int rc; char *p_path; char *r_path; ext2_ino_t ino; ext2_ino_t d_ino; struct ext2_vnode *vnode; struct ext2_inode *inode; struct ext2_inode d_inode; ext2_filsys e2fs = current_ext2fs(); debugf("source: %s, dest: %s", source, dest); rc = do_check(source); if (rc != 0) { debugf("do_check(%s); failed", source); return rc; } rc = do_check_split(dest, &p_path, &r_path); if (rc != 0) { debugf("do_check(%s); failed", dest); return rc; } debugf("parent: %s, child: %s", p_path, r_path); rc = do_readinode(e2fs, p_path, &d_ino, &d_inode); if (rc) { debugf("do_readinode(%s, &ino, &inode); failed", p_path); free_split(p_path, r_path); return rc; } rc = do_readvnode(e2fs, source, &ino, &vnode); if (rc) { debugf("do_readvnode(%s, &ino, &vnode); failed", source); free_split(p_path, r_path); return rc; } inode = vnode2inode(vnode); do { debugf("calling ext2fs_link(e2fs, %d, %s, %d, %d);", d_ino, r_path, ino, do_modetoext2lag(inode->i_mode)); rc = ext2fs_link(e2fs, d_ino, r_path, ino, do_modetoext2lag(inode->i_mode)); if (rc == EXT2_ET_DIR_NO_SPACE) { debugf("calling ext2fs_expand_dir(e2fs, &d)", d_ino); if (ext2fs_expand_dir(e2fs, d_ino)) { debugf("error while expanding directory %s (%d)", p_path, d_ino); vnode_put(vnode, 0); free_split(p_path, r_path); return -ENOSPC; } } } while (rc == EXT2_ET_DIR_NO_SPACE); if (rc) { debugf("ext2fs_link(e2fs, %d, %s, %d, %d); failed", d_ino, r_path, ino, do_modetoext2lag(inode->i_mode)); vnode_put(vnode, 0); free_split(p_path, r_path); return -EIO; } d_inode.i_mtime = d_inode.i_ctime = inode->i_ctime = e2fs->now ? e2fs->now : time(NULL); inode->i_links_count += 1; rc=vnode_put(vnode,1); if (rc) { debugf("vnode_put(vnode,1); failed"); free_split(p_path, r_path); return -EIO; } rc = ext2fs_write_inode(e2fs, d_ino, &d_inode); if (rc) { debugf("ext2fs_write_inode(e2fs, d_ino, &d_inode); failed"); free_split(p_path, r_path); return -EIO; } debugf("done"); return 0; }
int op_unlink (const char *path) { int rt; char *p_path; char *r_path; ino_t p_ino; struct ufs_vnode *p_vnode; ino_t r_ino; struct ufs_vnode *r_vnode; struct inode *r_inode; struct inode *p_inode; uufsd_t *ufs = current_ufs(); RETURN_IF_RDONLY(ufs); debugf("enter"); debugf("path = %s", path); rt = do_check_split(path, &p_path, &r_path); if (rt != 0) { debugf("do_check_split: failed"); return rt; } debugf("parent: %s, child: %s", p_path, r_path); rt = do_readvnode(ufs, p_path, &p_ino, &p_vnode); if (rt) { debugf("do_readinode(%s, &p_ino, &p_inode); failed", p_path); free_split(p_path, r_path); return rt; } rt = do_readvnode(ufs, path, &r_ino, &r_vnode); if (rt) { debugf("do_readvnode(%s, &r_ino, &r_vnode); failed", path); free_split(p_path, r_path); return rt; } r_inode = vnode2inode(r_vnode); if(S_ISDIR(r_inode->i_mode)) { debugf("%s is a directory", path); vnode_put(r_vnode, 0); free_split(p_path, r_path); return -EISDIR; } rt = ufs_unlink(ufs, p_ino, r_path, r_ino, 0); if (rt) { debugf("ufs_unlink(ufs, %d, %s, %d, 0); failed", p_ino, r_path, r_ino); vnode_put(r_vnode, 0); vnode_put(p_vnode, 0); free_split(p_path, r_path); return -EIO; } if (r_inode->i_nlink > 0) { r_inode->i_nlink -= 1; } p_inode = vnode2inode(p_vnode); p_inode->i_ctime = p_inode->i_mtime = ufs->now ? ufs->now : time(NULL); rt = vnode_put(p_vnode, 1); if (rt) { debugf("ufs_write_inode(ufs, p_ino, &p_inode); failed"); vnode_put(r_vnode,1); free_split(p_path, r_path); return -EIO; } r_inode->i_ctime = ufs->now ? ufs->now : time(NULL); rt = vnode_put(r_vnode, 1); if (rt) { debugf("vnode_put(r_vnode, 1); failed"); free_split(p_path, r_path); return -EIO; } free_split(p_path, r_path); debugf("leave"); return 0; }