/* Formats the file system. */ static void do_format (void) { struct dir *current_dir; printf ("Formatting file system..."); free_map_create (); /*Create directory with 2 entries - for . and .. */ if (!dir_create (ROOT_DIR_SECTOR, 2)) PANIC ("root directory creation failed"); free_map_close (); /* Create . and .. entries. */ current_dir = dir_open_root (); dir_add (current_dir, ".", ROOT_DIR_SECTOR, false); dir_add (current_dir, "..", ROOT_DIR_SECTOR, false); dir_close (current_dir); printf ("done.\n"); }
/* Creates a file named NAME with the given INITIAL_SIZE. Returns true if successful, false otherwise. Fails if a file named NAME already exists, or if internal memory allocation fails. */ bool filesys_create (const char *name, off_t initial_size,bool is_dir) { // printf("create start: %s\n",name); // printf("%s size: %d\n",name,initial_size); disk_sector_t inode_sector = 0; char *file_name = get_file_name(name); bool success=true; if( strcmp(file_name,"")==0 ) { return false; } // if( is_dir) // printf("mkdir!\n"); // printf("file name : %s\n",file_name); struct dir *dir = get_directory(name); // printf("sector of dir : %d\n", inode_get_inumber(dir_get_inode(dir))); // if( inode_get_parent(dir_get_inode(dir)) ==0 ) // { // printf("its on root directory!\n"); // } /* if(dir == NULL) { printf("no directory\n"); success=false; } if(!free_map_allocate(1,&inode_sector)) { printf("no free map\n"); success=false; } if(!inode_create(inode_sector,initial_size,is_dir)) { printf("inode create fail\n"); success=false; } if(!dir_add(dir,file_name,inode_sector)) { printf("dir add fail\n"); success=false; }*/ // printf("file name:%s\n",file_name); success = (dir != NULL && free_map_allocate (1, &inode_sector) && inode_create (inode_sector, initial_size, is_dir) && dir_add (dir, file_name, inode_sector)); if (!success && inode_sector != 0) { // printf("haha\n"); free_map_release (inode_sector, 1); } dir_close (dir); // printf("create end sector num : %d\n",inode_sector); free(file_name); return success; }
/* create directory file */ bool filesys_create_dir(const char *name) { struct dir *parent_dir; struct inode *parent_inode; struct inode *tmp; struct dir *new_dir; bool result = false; /* if dir name is NULL, return false*/ if(name == NULL) return result; /* copy name to cp_name */ char *cp_name = malloc( sizeof(char) * (strlen(name)+1) ); strlcpy(cp_name, name, strlen(name)+1 ); char *file_name; file_name = malloc( sizeof(char) * (strlen(name)+1) ); if(file_name == NULL) { free(cp_name); return result; } parent_dir = parse_path(cp_name, file_name); /* if already same name file exist in directory, return false*/ if(dir_lookup(parent_dir, file_name, &tmp) == true) return result; /* allocate bitmap */ block_sector_t sector_idx; free_map_allocate(1, §or_idx); /* create directory */ dir_create(sector_idx, 16); /* add new entry to parent directory */ dir_add(parent_dir, file_name, sector_idx); /* add entry '.' and '..' to directory */ new_dir = dir_open( inode_open(sector_idx) ); dir_add(new_dir,".",sector_idx); parent_inode = dir_get_inode(parent_dir); dir_add(new_dir,"..", inode_get_inumber(parent_inode)); free(cp_name); free(file_name); result = true; return result; }
/* Creates a directory in the given SECTOR. Returns true if successful, false on failure. */ bool dir_create (block_sector_t sector, block_sector_t parent) { bool status; struct dir *dir; /* Create sector with enough room for two entries */ status = inode_create (sector, 2 * sizeof (struct dir_entry), true); if (!status) return status; /* Add entries for '.' and '..' */ struct inode *i = inode_open (sector); dir = dir_open (i); if (dir == NULL) return false; dir_add (dir, ".", sector); dir_add (dir, "..", parent); dir_close (dir); return true; }
/*! Creates a file named NAME with the given INITIAL_SIZE. Returns true if successful, false otherwise. Fails if a file named NAME already exists, or if internal memory allocation fails. */ bool filesys_create(const char *name, off_t initial_size) { block_sector_t inode_sector = 0; struct dir *dir = dir_open_root(); bool success = (dir != NULL && free_map_allocate(1, &inode_sector) && inode_create(inode_sector, initial_size) && dir_add(dir, name, inode_sector)); if (!success && inode_sector != 0) free_map_release(inode_sector, 1); dir_close(dir); return success; }
directory * read_dir(FILE *f) { directory *dir; direntry entry; int n, pf, ret; char *line; time_t oldt, newt; dir = dir_new(); n = 0; pf = 0; oldt = 0; init_parse_time(); while ((line=ftp_gets(f)) != NULL) { while ((ret=pfunc[pf](&entry, line)) == -1) { pf++; if (pf >= npfunc) { pf = 0; ret = 1; break; } } if (ret == 0) { dir_add(dir, &entry); n++; } free(line); if ((newt=time(NULL)) != oldt) { disp_status(DISP_STATUS, "listed %d", n); oldt = newt; } } #if 0 if (n == 0) { dir->line = (direntry *)malloc(sizeof(direntry)); dir->line->line = strdup(""); dir->line->type = 'x'; dir->line->name = strdup(""); dir->line->link = NULL; n = 1; } #endif return dir; }
/* Creates a file named NAME with the given INITIAL_SIZE. Returns true if successful, false otherwise. Fails if a file named NAME already exists, or if internal memory allocation fails. */ bool filesys_create (const char *path, off_t initial_size) { char *name = get_filename (path); block_sector_t inode_sector = 0; struct dir *dir = dir_get (path); bool success = (dir != NULL && free_map_allocate (1, &inode_sector) && inode_create (inode_sector, initial_size, false) && dir_add (dir, name, inode_sector)); if (!success && inode_sector != 0) free_map_release (inode_sector, 1); dir_close (dir); free (name); return success; }
/* Creates a file named NAME with the given INITIAL_SIZE. Returns true if successful, false otherwise. Fails if a file named NAME already exists, or if internal memory allocation fails. */ bool filesys_create (const char *name, off_t initial_size, bool is_dir) { block_sector_t inode_sector = 0; struct dir *dir = containing_dir(name); char* file_name = get_name(name); bool success = false; if (strcmp(file_name, ".") != 0 && strcmp(file_name, "..") != 0){ success = (dir != NULL && free_map_allocate (1, &inode_sector) && inode_create (inode_sector, initial_size, is_dir) && dir_add (dir, file_name, inode_sector)); } if (!success && inode_sector != 0) free_map_release (inode_sector, 1); dir_close (dir); free(file_name); return success; }
/*! Creates the directory named dir. Return true if successful, but false * if dir already exists or if any directory name in dir, besides the last * one does not exist. */ bool _mkdir(const char* dir) { /* Inode for the new directory created. */ struct inode* next_inode; /* Parent directory. */ struct dir* cur_dir; /* Name of the directory. */ char name[15]; /* Sector number allocated to the new directory. */ block_sector_t sector; /* Check the validity of the pointer*/ if (!checkva(dir)) exit(-1); /* The compose the path to a final dir name and its parent directory. */ if (!decompose_dir(dir, name, &cur_dir)){ return false; } ASSERT(cur_dir != NULL); /* Allocate a new sector for this new directory; * Create a new directory */ if (!free_map_allocate(1, §or) || !dir_create(sector, 0, dir_get_inode(cur_dir)->sector)){ dir_close(cur_dir); return false; } /* Add the new directory to its parent directory. */ if (!dir_add(cur_dir, name, sector)){ free_map_release(sector, 1); dir_close(cur_dir); return false; } dir_close(cur_dir); return true; }
/* Creates a file named NAME with the given INITIAL_SIZE. Returns true if successful, false otherwise. Fails if a file named NAME already exists, or if internal memory allocation fails. */ bool filesys_create (const char *name, off_t initial_size) { block_sector_t inode_sector = 0; struct thread *cur = thread_current(); struct dir *dir; if(cur->current_directory == NULL) dir = dir_open_root (); else dir = dir_open_current(); bool success = (dir != NULL && free_map_allocate (1, &inode_sector) && inode_create (inode_sector, initial_size, false) && dir_add (dir, name, inode_sector)); if (!success && inode_sector != 0) free_map_release (inode_sector, 1); dir_close (dir); return success; }
/* Creates a file named NAME with the given INITIAL_SIZE. Returns true if successful, false otherwise. Fails if a file named NAME already exists, or if internal memory allocation fails. */ bool filesys_create (const char *name, off_t initial_size) { char *cp_name = malloc( sizeof(char) * (strlen(name) + 1) ); char *file_name = malloc( sizeof(char) * (strlen(name) + 1) ); if( cp_name == NULL || file_name == NULL) return false; strlcpy(cp_name, name, strlen(name)+1); block_sector_t inode_sector = 0; struct dir *dir = parse_path (cp_name, file_name); bool success = (dir != NULL && free_map_allocate (1, &inode_sector) && inode_create (inode_sector, initial_size, IS_FILE) && dir_add (dir, file_name, inode_sector)); if (!success && inode_sector != 0) free_map_release (inode_sector, 1); dir_close (dir); free(cp_name); free(file_name); return success; }
/* Creates a file named NAME with the given INITIAL_SIZE. Returns true if successful, false otherwise. Fails if a file named NAME already exists, or if internal memory allocation fails. */ bool filesys_create (const char *name, off_t initial_size, bool is_dir) { block_sector_t inode_sector = 0; /* Start of Project 4 */ bool success = false; struct dir *dir = dir_from_path (name); char* file_name = retrieve_file_name (name); if (strcmp(file_name, ".") != 0 && strcmp(file_name, "..") != 0) { success = (dir != NULL && free_map_allocate (1, &inode_sector) && inode_create (inode_sector, initial_size, is_dir) && dir_add (dir, file_name, inode_sector)); } free(file_name); /* End of Project 4 */ if (!success && inode_sector != 0) free_map_release (inode_sector, 1); dir_close (dir); return success; }
static int catsearch(struct vol *vol, struct dir *dir, int rmatches, uint32_t *pos, char *rbuf, uint32_t *nrecs, int *rsize, int ext) { static u_int32_t cur_pos; /* Saved position index (ID) - used to remember "position" across FPCatSearch calls */ static DIR *dirpos; /* UNIX structure describing currently opened directory. */ struct dir *currentdir; /* struct dir of current directory */ int cidx, r; struct dirent *entry; int result = AFP_OK; int ccr; struct path path; char *vpath = vol->v_path; char *rrbuf = rbuf; time_t start_time; int num_rounds = NUM_ROUNDS; int cwd = -1; int error; int unlen; if (*pos != 0 && *pos != cur_pos) { result = AFPERR_CATCHNG; goto catsearch_end; } /* FIXME: Category "offspring count ! */ /* We need to initialize all mandatory structures/variables and change working directory appropriate... */ if (*pos == 0) { clearstack(); if (dirpos != NULL) { closedir(dirpos); dirpos = NULL; } if (addstack(vpath, dir, -1) == -1) { result = AFPERR_MISC; goto catsearch_end; } /* FIXME: Sometimes DID is given by client ! (correct this one above !) */ } /* Save current path */ if ((cwd = open(".", O_RDONLY)) < 0) { result = AFPERR_MISC; goto catsearch_end; } /* So we are beginning... */ start_time = time(NULL); while ((cidx = reducestack()) != -1) { if ((currentdir = dirlookup(vol, dstack[cidx].ds_did)) == NULL) { result = AFPERR_MISC; goto catsearch_end; } LOG(log_debug, logtype_afpd, "catsearch: current struct dir: \"%s\"", cfrombstr(currentdir->d_fullpath)); error = movecwd(vol, currentdir); if (!error && dirpos == NULL) dirpos = opendir("."); if (dirpos == NULL) dirpos = opendir(bdata(currentdir->d_fullpath)); if (error || dirpos == NULL) { switch (errno) { case EACCES: dstack[cidx].ds_checked = 1; continue; case EMFILE: case ENFILE: case ENOENT: result = AFPERR_NFILE; break; case ENOMEM: case ENOTDIR: default: result = AFPERR_MISC; } /* switch (errno) */ goto catsearch_end; } while ((entry = readdir(dirpos)) != NULL) { (*pos)++; if (!check_dirent(vol, entry->d_name)) continue; LOG(log_debug, logtype_afpd, "catsearch(\"%s\"): dirent: \"%s\"", cfrombstr(currentdir->d_fullpath), entry->d_name); memset(&path, 0, sizeof(path)); path.u_name = entry->d_name; if (of_stat(vol, &path) != 0) { switch (errno) { case EACCES: case ELOOP: case ENOENT: continue; case ENOTDIR: case EFAULT: case ENOMEM: case ENAMETOOLONG: default: result = AFPERR_MISC; goto catsearch_end; } } switch (S_IFMT & path.st.st_mode) { case S_IFDIR: /* here we can short cut ie if in the same loop the parent dir wasn't in the cache ALL dirsearch_byname will fail. */ unlen = strlen(path.u_name); path.d_dir = dircache_search_by_name(vol, currentdir, path.u_name, unlen); if (path.d_dir == NULL) { /* path.m_name is set by adddir */ if ((path.d_dir = dir_add(vol, currentdir, &path, unlen)) == NULL) { result = AFPERR_MISC; goto catsearch_end; } } path.m_name = cfrombstr(path.d_dir->d_m_name); if (addstack(path.u_name, path.d_dir, cidx) == -1) { result = AFPERR_MISC; goto catsearch_end; } break; case S_IFREG: path.d_dir = currentdir; break; default: continue; } ccr = crit_check(vol, &path); /* bit 0 means that criteria has been met */ if ((ccr & 1)) { r = rslt_add ( vol, &path, &rrbuf, ext); if (r == 0) { result = AFPERR_MISC; goto catsearch_end; } *nrecs += r; /* Number of matches limit */ if (--rmatches == 0) goto catsearch_pause; /* Block size limit */ if (rrbuf - rbuf >= 448) goto catsearch_pause; } /* MacOS 9 doesn't like servers executing commands longer than few seconds */ if (--num_rounds <= 0) { if (start_time != time(NULL)) { result=AFP_OK; goto catsearch_pause; } num_rounds = NUM_ROUNDS; } } /* while ((entry=readdir(dirpos)) != NULL) */ closedir(dirpos); dirpos = NULL; dstack[cidx].ds_checked = 1; } /* while (current_idx = reducestack()) != -1) */ /* We have finished traversing our tree. Return EOF here. */ result = AFPERR_EOF; goto catsearch_end; catsearch_pause: cur_pos = *pos; save_cidx = cidx; catsearch_end: /* Exiting catsearch: error condition */ *rsize = rrbuf - rbuf; if (cwd != -1) { if ((fchdir(cwd)) != 0) { LOG(log_debug, logtype_afpd, "error chdiring back: %s", strerror(errno)); } close(cwd); } return result; } /* catsearch() */
/* Creates a file named NAME with the given INITIAL_SIZE. Returns true if successful, false otherwise. Fails if a file named NAME already exists, or if internal memory allocation fails. */ bool filesys_create (const char *name, off_t initial_size, uint32_t is_dir) { block_sector_t inode_sector = (block_sector_t) -1; struct inode *inode = NULL; struct dir *search_dir = get_cwd(name); if (search_dir == NULL) { return false; } char *part = malloc(NAME_MAX + 1); if (part == NULL) { return false; } memset(part, 0, NAME_MAX + 1); int retrieved_next_part; for (retrieved_next_part = get_next_part(part, &name); retrieved_next_part > 0; retrieved_next_part = get_next_part(part, &name)) { if (dir_lookup (search_dir, part, &inode)) { if (!inode_is_dir(inode)) { break; } else { dir_close(search_dir); search_dir = dir_open(inode); if (search_dir == NULL) { free(part); return false; } } } else { inode = NULL; break; } } if (inode != NULL || get_next_part(part, &name) != 0) { if (inode != NULL && !inode_is_dir(inode)) { inode_close(inode); } dir_close(search_dir); free(part); return false; } bool success = false; if (is_dir) { block_sector_t parent_sector = inode_get_inumber(dir_get_inode(search_dir)); success = (search_dir != NULL && free_map_allocate (1, &inode_sector) && dir_create (inode_sector, initial_size, parent_sector) && dir_add (search_dir, part, inode_sector)); } else { success = (search_dir != NULL && free_map_allocate (1, &inode_sector) && inode_create (inode_sector, initial_size, is_dir) && dir_add (search_dir, part, inode_sector)); } if (!success) free_map_release (inode_sector, 1); dir_close (search_dir); free(part); return success; }
static void add_dotdot(struct gfs2_inode *ip) { struct dir_info *di; struct gfs2_sbd *sdp = ip->i_sbd; int err; log_info( _("Adding .. entry to directory %llu (0x%llx) pointing back " "to lost+found\n"), (unsigned long long)ip->i_di.di_num.no_addr, (unsigned long long)ip->i_di.di_num.no_addr); /* If there's a pre-existing .. directory entry, we have to back out the links. */ di = dirtree_find(ip->i_di.di_num.no_addr); if (di && valid_block(sdp, di->dotdot_parent.no_addr)) { struct gfs2_inode *dip; log_debug(_("Directory (0x%llx) already had a " "\"..\" link to (0x%llx).\n"), (unsigned long long)ip->i_di.di_num.no_addr, (unsigned long long)di->dotdot_parent.no_addr); dip = fsck_load_inode(sdp, di->dotdot_parent.no_addr); if (dip->i_di.di_num.no_formal_ino == di->dotdot_parent.no_formal_ino) { decr_link_count(di->dotdot_parent.no_addr, ip->i_di.di_num.no_addr, sdp->gfs1, _(".. unlinked, moving to lost+found")); if (dip->i_di.di_nlink > 0) { dip->i_di.di_nlink--; set_di_nlink(dip); /* keep inode tree in sync */ log_debug(_("Decrementing its links to %d\n"), dip->i_di.di_nlink); bmodified(dip->i_bh); } else if (!dip->i_di.di_nlink) { log_debug(_("Its link count is zero.\n")); } else { log_debug(_("Its link count is %d! Changing " "it to 0.\n"), dip->i_di.di_nlink); dip->i_di.di_nlink = 0; set_di_nlink(dip); /* keep inode tree in sync */ bmodified(dip->i_bh); } } else { log_debug(_("Directory (0x%llx)'s link to parent " "(0x%llx) had a formal inode discrepancy: " "was 0x%llx, expected 0x%llx\n"), (unsigned long long)ip->i_di.di_num.no_addr, (unsigned long long)di->dotdot_parent.no_addr, di->dotdot_parent.no_formal_ino, dip->i_di.di_num.no_formal_ino); log_debug(_("The parent directory was not changed.\n")); } fsck_inode_put(&dip); di = NULL; } else { if (di) log_debug(_("Couldn't find a valid \"..\" entry " "for orphan directory (0x%llx): " "'..' = 0x%llx\n"), (unsigned long long)ip->i_di.di_num.no_addr, (unsigned long long)di->dotdot_parent.no_addr); else log_debug(_("Couldn't find directory (0x%llx) " "in directory tree.\n"), (unsigned long long)ip->i_di.di_num.no_addr); } if (gfs2_dirent_del(ip, "..", 2)) log_warn( _("add_inode_to_lf: Unable to remove " "\"..\" directory entry.\n")); err = dir_add(ip, "..", 2, &(lf_dip->i_di.di_num), (sdp->gfs1 ? GFS_FILE_DIR : DT_DIR)); if (err) { log_crit(_("Error adding .. directory: %s\n"), strerror(errno)); exit(FSCK_ERROR); } }
/* add_inode_to_lf - Add dir entry to lost+found for the inode * @ip: inode to add to lost + found * * This function adds an entry into the lost and found dir * for the given inode. The name of the entry will be * "lost_<ip->i_num.no_addr>". * * Returns: 0 on success, -1 on failure. */ int add_inode_to_lf(struct gfs2_inode *ip){ char tmp_name[256]; __be32 inode_type; struct gfs2_sbd *sdp = ip->i_sbd; int err = 0; uint32_t mode; make_sure_lf_exists(ip); if (ip->i_di.di_num.no_addr == lf_dip->i_di.di_num.no_addr) { log_err( _("Trying to add lost+found to itself...skipping")); return 0; } if (sdp->gfs1) mode = gfs_to_gfs2_mode(ip); else mode = ip->i_di.di_mode & S_IFMT; switch (mode) { case S_IFDIR: add_dotdot(ip); sprintf(tmp_name, "lost_dir_%llu", (unsigned long long)ip->i_di.di_num.no_addr); inode_type = (sdp->gfs1 ? GFS_FILE_DIR : DT_DIR); break; case S_IFREG: sprintf(tmp_name, "lost_file_%llu", (unsigned long long)ip->i_di.di_num.no_addr); inode_type = (sdp->gfs1 ? GFS_FILE_REG : DT_REG); break; case S_IFLNK: sprintf(tmp_name, "lost_link_%llu", (unsigned long long)ip->i_di.di_num.no_addr); inode_type = (sdp->gfs1 ? GFS_FILE_LNK : DT_LNK); break; case S_IFBLK: sprintf(tmp_name, "lost_blkdev_%llu", (unsigned long long)ip->i_di.di_num.no_addr); inode_type = (sdp->gfs1 ? GFS_FILE_BLK : DT_BLK); break; case S_IFCHR: sprintf(tmp_name, "lost_chrdev_%llu", (unsigned long long)ip->i_di.di_num.no_addr); inode_type = (sdp->gfs1 ? GFS_FILE_CHR : DT_CHR); break; case S_IFIFO: sprintf(tmp_name, "lost_fifo_%llu", (unsigned long long)ip->i_di.di_num.no_addr); inode_type = (sdp->gfs1 ? GFS_FILE_FIFO : DT_FIFO); break; case S_IFSOCK: sprintf(tmp_name, "lost_socket_%llu", (unsigned long long)ip->i_di.di_num.no_addr); inode_type = (sdp->gfs1 ? GFS_FILE_SOCK : DT_SOCK); break; default: sprintf(tmp_name, "lost_%llu", (unsigned long long)ip->i_di.di_num.no_addr); inode_type = (sdp->gfs1 ? GFS_FILE_REG : DT_REG); break; } err = dir_add(lf_dip, tmp_name, strlen(tmp_name), &(ip->i_di.di_num), inode_type); if (err) { log_crit(_("Error adding directory %s: %s\n"), tmp_name, strerror(errno)); exit(FSCK_ERROR); } /* This inode is linked from lost+found */ incr_link_count(ip->i_di.di_num, lf_dip, _("from lost+found")); /* If it's a directory, lost+found is back-linked to it via .. */ if (mode == S_IFDIR) incr_link_count(lf_dip->i_di.di_num, ip, _("to lost+found")); log_notice( _("Added inode #%llu (0x%llx) to lost+found\n"), (unsigned long long)ip->i_di.di_num.no_addr, (unsigned long long)ip->i_di.di_num.no_addr); gfs2_dinode_out(&lf_dip->i_di, lf_dip->i_bh->b_data); bwrite(lf_dip->i_bh); return 0; }
/* Creates a file named NAME with the given INITIAL_SIZE. Returns true if successful, false otherwise. Fails if a file named NAME already exists, or if internal memory allocation fails. */ bool filesys_create (const char *name, off_t initial_size) { char name_copy[MAX_FULL_PATH]; char *file_name = NULL; char *token, *save_ptr; block_sector_t inode_sector = 0; /* Null file name not allowed. */ if (name[0] == '\0') { return false; } if (strlen (name) > MAX_FULL_PATH) { return false; } /* Open parent directory. */ struct dir *dir = recursive_dir_open (name); if (!dir) { return false; } /* extract only file name from entire path. */ strlcpy (name_copy, name, strlen (name) + 1); for (token = strtok_r (name_copy, "/", &save_ptr); token != NULL; token = strtok_r (NULL, "/", &save_ptr)) { file_name = token; } if (file_name[0] == '\0') { dir_close (dir); return false; } if (strlen (file_name) > NAME_MAX) { dir_close (dir); return false; } /* Check for and prevent simultaneous accesses. */ struct list_elem *e; block_sector_t parent_dir_sector = inode_get_inumber (dir_get_inode (dir)); lock_acquire (&cur_name_list_lock); for (e = list_begin (&cur_name_list); e != list_end (&cur_name_list); e = list_next (e)) { struct cur_name_list_entry *cur_name_list_entry = NULL; cur_name_list_entry = list_entry (e, struct cur_name_list_entry, elem); if ((cur_name_list_entry->parent_dir_sector == parent_dir_sector) && (!strcmp (file_name, cur_name_list_entry->file_name))) { dir_close (dir); return false; } } struct cur_name_list_entry *name_entry = NULL; name_entry = malloc (sizeof (struct cur_name_list_entry)); if (name_entry == NULL) { dir_close (dir); lock_release (&cur_name_list_lock); return false; } strlcpy (name_entry->file_name, file_name, strlen (file_name) + 1); name_entry->parent_dir_sector = parent_dir_sector; list_push_back (&cur_name_list, &name_entry->elem); lock_release (&cur_name_list_lock); /* Create file. and add directory entry. */ bool success = (dir != NULL && free_map_allocate (1, &inode_sector) && inode_create (inode_sector, initial_size) && dir_add (dir, file_name, inode_sector, true)); if (!success && inode_sector != 0) free_map_release (inode_sector, 1); dir_close (dir); lock_acquire (&cur_name_list_lock); list_remove (&name_entry->elem); lock_release (&cur_name_list_lock); free (name_entry); return success; }
static void peer_add_dir (void *msg) { fs_msg_s *m = msg; FN; dir_add(m->dir_parent_id, m->dir_id, m->dir_name); }
nfsstat4 nfs_op_link(struct nfs_cxn *cxn, const LINK4args *args, struct list_head *writes, struct rpc_write **wr) { nfsstat4 status; struct nfs_inode *dir_ino = NULL, *src_ino = NULL; struct nfs_buf newname; uint64_t before = 0, after = 0; DB_TXN *txn; DB_ENV *dbenv = srv.fsdb.env; int rc; newname.len = args->newname.utf8string_len; newname.val = args->newname.utf8string_val; if (debugging) applog(LOG_INFO, "op LINK (%.*s)", newname.len, newname.val); /* verify input parameters */ if (!valid_fh(cxn->current_fh) || !valid_fh(cxn->save_fh)) { status = NFS4ERR_NOFILEHANDLE; goto out; } if (newname.len > SRV_MAX_NAME) { status = NFS4ERR_NAMETOOLONG; goto out; } /* open transaction */ rc = dbenv->txn_begin(dbenv, NULL, &txn, 0); if (rc) { status = NFS4ERR_IO; dbenv->err(dbenv, rc, "DB_ENV->txn_begin"); goto out; } /* read source inode's directory inode */ dir_ino = inode_fhdec(txn, cxn->current_fh, 0); if (!dir_ino) { status = NFS4ERR_NOFILEHANDLE; goto out_abort; } /* make sure target is a directory */ if (dir_ino->type != NF4DIR) { status = NFS4ERR_NOTDIR; goto out_abort; } /* read source inode */ src_ino = inode_fhdec(txn, cxn->save_fh, 0); if (!src_ino) { status = NFS4ERR_NOFILEHANDLE; goto out_abort; } /* make sure source is a not a directory */ if (src_ino->type == NF4DIR) { status = NFS4ERR_ISDIR; goto out_abort; } before = dir_ino->version; /* add directory entry */ status = dir_add(txn, dir_ino, &newname, src_ino); if (status != NFS4_OK) goto out_abort; after = dir_ino->version; /* update source inode */ src_ino->n_link++; if (inode_touch(txn, src_ino)) { status = NFS4ERR_IO; goto out_abort; } /* close transaction */ rc = txn->commit(txn, 0); if (rc) { dbenv->err(dbenv, rc, "DB_ENV->txn_commit"); status = NFS4ERR_IO; goto out; } out: WR32(status); if (status == NFS4_OK) { WR32(1); /* cinfo.atomic */ WR64(before); /* cinfo.before */ WR64(after); /* cinfo.after */ } inode_free(src_ino); inode_free(dir_ino); return status; out_abort: if (txn->abort(txn)) dbenv->err(dbenv, rc, "DB_ENV->txn_abort"); goto out; }
/* Creates a file named NAME with the given INITIAL_SIZE. Returns true if successful, false otherwise. Fails if a file named NAME already exists, or if internal memory allocation fails. */ static bool _filesys_create (const char *full_path, off_t initial_size, bool is_dir) { block_sector_t cwd = thread_current ()->cwd_sector; bool found = true; if (cwd != (block_sector_t) ROOT_DIR_SECTOR) { struct inode *curr = NULL; curr = inode_open (cwd); struct dir *p; p = dir_open (inode_open (curr->data.parent_dir_sector)); struct dir_entry e; size_t ofs; ASSERT (p != NULL); found = false; for (ofs = 0; inode_read_at (p->inode, &e, sizeof e, ofs) == sizeof e; ofs += sizeof e) { if (e.inode_sector == cwd && e.in_use) { found = true; break; } } } if (!found) return false; char leaf_name[NAME_MAX + 1]; if (!dir_get_leaf_name (full_path, leaf_name)) return false; struct dir *parent_dir = dir_get_parent_dir (full_path); if (parent_dir == NULL) return false; block_sector_t inode_sector = 0; if (!free_map_allocate_one (&inode_sector)) { dir_close (parent_dir); return false; } bool success = is_dir? dir_create (inode_sector, BLOCK_SECTOR_SIZE / sizeof (struct dir_entry)) : inode_create (inode_sector, initial_size); if (!success) { free_map_release (inode_sector, 1); dir_close (parent_dir); return false; } if (!dir_add (parent_dir, leaf_name, inode_sector)) { inode_remove (inode_open (inode_sector)); free_map_release (inode_sector, 1); dir_close (parent_dir); return false; } dir_close (parent_dir); return true; }