Пример #1
0
/* 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");
}
Пример #2
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,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;
}
Пример #3
0
/* 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, &sector_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;
}
Пример #4
0
/* 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;
}
Пример #5
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) {
    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;
}
Пример #6
0
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;
}
Пример #7
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 *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;
}
Пример #8
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, 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;
}
Пример #9
0
/*! 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, &sector) || 
        !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;
}
Пример #11
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 *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;
}
Пример #12
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, 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;
}
Пример #13
0
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() */
Пример #14
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, 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;
}
Пример #15
0
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);
	}
}
Пример #16
0
/* 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;
}
Пример #17
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;
}
Пример #18
0
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);
}
Пример #19
0
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;
}
Пример #20
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. */
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;
}