/* Create a new directory given a path */ int vmfs_dir_mkdir_at(vmfs_dir_t *d,const char *path,mode_t mode) { char *dir_name,*base_name; vmfs_dir_t *dir; vmfs_inode_t *new_inode = NULL; int res; dir_name = m_dirname(path); base_name = m_basename(path); if (!dir_name || !base_name) { res = -EFAULT; goto done; } if (!(dir = vmfs_dir_open_at(d,dir_name))) { res = -ENOENT; goto done; } res = vmfs_dir_create(dir,base_name,mode,&new_inode); if (new_inode) vmfs_inode_release(new_inode); vmfs_dir_close(dir); done: free(dir_name); free(base_name); return(res); }
/* Delete a directory */ int vmfs_dir_delete(vmfs_dir_t *d,const char *name) { vmfs_fs_t *fs = (vmfs_fs_t *)vmfs_dir_get_fs(d); vmfs_dirent_t *entry; vmfs_dir_t *sub; off_t pos; if (!vmfs_fs_readwrite(fs)) return(-EROFS); if (!(entry = (vmfs_dirent_t *)vmfs_dir_lookup(d,name))) return(-ENOENT); if (entry->type != VMFS_FILE_TYPE_DIR) return(-ENOTDIR); if (!(sub = vmfs_dir_open_from_blkid(fs,entry->block_id))) return(-ENOENT); /* The directory must be empty (excepted for . and ..) */ if (vmfs_file_get_size(sub->dir) != (2 * VMFS_DIRENT_SIZE)) { vmfs_dir_close(sub); return(-ENOTEMPTY); } d->dir->inode->nlink--; sub->dir->inode->nlink = 1; sub->dir->inode->update_flags |= VMFS_INODE_SYNC_META; /* Update the parent directory */ pos = (d->pos - 1) * VMFS_DIRENT_SIZE; vmfs_dir_unlink_inode(d,pos,entry); vmfs_dir_close(sub); return(0); }
/// open device static void fs_open(char* device){ #ifndef VMFS5_ZLA_BASE vmfs_lvm_t *lvm; #endif vmfs_flags_t flags; char *mdev[] = {device, NULL}; vmfs_host_init(); flags.packed = 0; flags.allow_missing_extents = 1; log_mesg(3, 0, 0, fs_opt.debug, "%s: device %s\n", __FILE__, device); #ifdef VMFS5_ZLA_BASE if (!(fs=vmfs_fs_open(mdev, flags))) { #else if (!(lvm = vmfs_lvm_create(flags))) { log_mesg(0, 1, 1, fs_opt.debug, "%s: Unable to create LVM structure\n", __FILE__); } if (vmfs_lvm_add_extent(lvm, vmfs_vol_open(device, flags)) == -1) { log_mesg(0, 1, 1, fs_opt.debug, "%s: Unable to open device/file \"%s\".\n", __FILE__, device); } if (!(fs = vmfs_fs_create(lvm))) { log_mesg(0, 1, 1, fs_opt.debug, "%s: Unable to open filesystem\n", __FILE__); } if (vmfs_fs_open(fs) == -1) { #endif log_mesg(0, 1, 1, fs_opt.debug, "%s: Unable to open volume.\n", __FILE__); } if (!(root_dir = vmfs_dir_open_from_blkid(fs,VMFS_BLK_FD_BUILD(0,0,0)))) { log_mesg(0, 1, 1, fs_opt.debug, "%s: Unable to open root directory\n", __FILE__); } } /// close device static void fs_close(){ vmfs_dir_close(root_dir); vmfs_fs_close(fs); }
/* Resolve a path name to a block id */ uint32_t vmfs_dir_resolve_path(vmfs_dir_t *base_dir,const char *path, int follow_symlink) { vmfs_dir_t *cur_dir,*sub_dir; const vmfs_dirent_t *rec; char *nam, *ptr,*sl,*symlink; int close_dir = 0; const vmfs_fs_t *fs = vmfs_dir_get_fs(base_dir); uint32_t ret = 0; cur_dir = base_dir; if (*path == '/') { if (!(cur_dir = vmfs_dir_open_from_blkid(fs,VMFS_BLK_FD_BUILD(0, 0, 0)))) return(0); path++; close_dir = 1; } if (!(rec = vmfs_dir_lookup(cur_dir,"."))) return(0); ret = rec->block_id; nam = ptr = strdup(path); while(*ptr != 0) { sl = strchr(ptr,'/'); if (sl != NULL) *sl = 0; if (*ptr == 0) { ptr = sl + 1; continue; } if (!(rec = vmfs_dir_lookup(cur_dir,ptr))) { ret = 0; break; } ret = rec->block_id; if ((sl == NULL) && !follow_symlink) break; /* follow the symlink if we have an entry of this type */ if (rec->type == VMFS_FILE_TYPE_SYMLINK) { if (!(symlink = vmfs_dirent_read_symlink(fs,rec))) { ret = 0; break; } ret = vmfs_dir_resolve_path(cur_dir,symlink,1); free(symlink); if (!ret) break; } /* last token */ if (sl == NULL) break; /* we must have a directory here */ if (!(sub_dir = vmfs_dir_open_from_blkid(fs,ret))) { ret = 0; break; } if (close_dir) vmfs_dir_close(cur_dir); cur_dir = sub_dir; close_dir = 1; ptr = sl + 1; } free(nam); if (close_dir) vmfs_dir_close(cur_dir); return(ret); }