Exemplo n.º 1
0
static int nfs_rename(struct inode *old_dir, const char *old_name, int old_len,
		      struct inode *new_dir, const char *new_name, int new_len,
		      int must_be_dir)
{
	int error;

	if (!old_dir || !S_ISDIR(old_dir->i_mode)) {
		printk("nfs_rename: old inode is NULL or not a directory\n");
		iput(old_dir);
		iput(new_dir);
		return -ENOENT;
	}
	if (!new_dir || !S_ISDIR(new_dir->i_mode)) {
		printk("nfs_rename: new inode is NULL or not a directory\n");
		iput(old_dir);
		iput(new_dir);
		return -ENOENT;
	}
	if (old_len > NFS_MAXNAMLEN || new_len > NFS_MAXNAMLEN) {
		iput(old_dir);
		iput(new_dir);
		return -ENAMETOOLONG;
	}
	error = nfs_proc_rename(NFS_SERVER(old_dir),
		NFS_FH(old_dir), old_name,
		NFS_FH(new_dir), new_name,
		must_be_dir);

	nfs_lookup_cache_remove(old_dir, NULL, old_name);
	nfs_lookup_cache_remove(new_dir, NULL, new_name);
	iput(old_dir);
	iput(new_dir);
	return error;
}
Exemplo n.º 2
0
static int nfs_sillyrename(struct inode *dir, const char *name, int len)
{
	struct inode	*inode;
	char		silly[16];
	int		slen, ret;

	dir->i_count++;
	if (nfs_lookup(dir, name, len, &inode) < 0)
		return -EIO;		/* arbitrary */
	if (inode->i_count == 1 || NFS_RENAMED_DIR(inode)) {
		iput(inode);
		return -EIO;
	}
	slen = sprintf(silly, ".nfs%ld", inode->i_ino);

	if (len == slen && !strncmp(name, silly, len)) {
		iput(inode);
		return -EIO;		/* DWIM */
	}
	ret = nfs_proc_rename(NFS_SERVER(dir), NFS_FH(dir), name,
					       NFS_FH(dir), silly, 0);
	if (ret >= 0) {
		nfs_lookup_cache_remove(dir, NULL, name);
		nfs_lookup_cache_remove(dir, NULL, silly);
		NFS_RENAMED_DIR(inode) = dir;
		dir->i_count++;
	}
	iput(inode);
	return ret;
}
Exemplo n.º 3
0
int 
nfs_rename(struct file *filpfrom, const char *namefrom, 
	   struct file *filpto,   const char *nameto) {
    /* it will be guaranteed that both filp are the same type
       I guess I will have to make sure that they are in the same 
       server ??
       */
    struct nfs_fh *fhandlefrom, *fhandleto;
    int status;

    DPRINTF(CLU_LEVEL,("nfs_rename:\n"));

    if (namefrom == NULL || nameto == NULL) {
	errno = EFAULT;
	return -1;
    } else if (*namefrom == (char)NULL || *nameto == (char)NULL) {
	errno = ENOENT;
	return -1;
    }
    
    demand(filpfrom, bogus filp);
    demand(filpto, bogus filp);
    demand(filpfrom->op_type == filpto->op_type,
	   filpfrom and filpto are of different types!!);
    
    fhandlefrom = GETFHANDLE(filpfrom);
    fhandleto = GETFHANDLE(filpto);

    status = nfs_proc_rename(fhandlefrom,namefrom,
			     fhandleto, nameto);
			     
    if (status != 0) {
	errno = status;
	return -1;
    } else {
      nfs_cache_remove(filpfrom,namefrom);
      nfs_cache_remove(filpto,nameto); /* should be adding this entry */
      nfs_flush_filp(filpfrom);
      if (filpfrom != filpto) nfs_flush_filp(filpto);
      return 0;
    }
}
Exemplo n.º 4
0
/* The following X functions affect are the only ones that affect the name
 cache (and the directory cache):
 nfs_open (in file nfs_lookup_cache.c),
 nfs_lookup (in file nfs_lookup_cache.c),
 nfs_link,
 nfs_symlink,
 nfs_mkdir,
 nfs_rmdir,
 nfs_rename 
 */
int 
nfs_unlink(struct file *dirp, const char *name) {
  nfsc_p d,f;
  int dev;
  struct nfs_fh *fhandle;
  int status,lookup_status;

  DPRINTF(CLU_LEVEL,("** nfs_unlink %s\n",name));
  demand(dirp, bogus filp);
  d = GETNFSCE(dirp);
  fhandle = GETFHANDLE(dirp);
  dev = FHGETDEV(fhandle);

  lookup_status = nfs_cache_lookup(dev,GETNFSCEINO(d),name,&f);
  switch(lookup_status) {
  case -1: 
    /* negative cache hit, treat it as a miss to be sure is properly removed */
  case 0:
    /* cache miss */
    {
      struct nfs_fh fhandle2;
      struct nfs_fattr temp_fattr;
      
      k2printf("nfs_unlink: nfs_proc_lookup %s\n",name);
      status = nfs_proc_lookup(fhandle,
			       name,
			       &fhandle2,
			       &temp_fattr);

      if (status != 0) {
	errno = status;
	return -1;
      } 

      f = nfsc_get(dev,temp_fattr.fileid);
      nfs_fill_stat(&temp_fattr, f);
      
    }
  /* fall-through now that we have setup f */
  case 1:
    /* cache hit */
    if (nfsc_get_refcnt(f) == 1) {
      /* last copy */
      if (S_ISDIR(nfsc_get_mode(f))) {
        status = nfs_proc_rmdir(fhandle, name);
	//fprintf(stderr,"rmdir  status %d\n",status);
      } else {
	status = nfs_proc_remove(fhandle,name);
	//fprintf(stderr,"remove status %d\n",status);
      }
      if (status == 0) {
	nfs_cache_remove(dirp,NULL);
	nfs_flush_filp(dirp);
      }

      nfsc_put(f);
      if (status != 0) {
	errno = status; return -1;
      } 
      return 0;


    } else {
      /* has other references */
      static int i = 0;
      char difname[NAME_MAX];
      //fprintf(stderr,"removing a file that is still referenced: %s\n",name);
      demand (!(S_ISDIR(f->sb.st_mode)), removing last ref directory);
      if (i == 0) atexit(nfs_process_unlinkatend);
      sprintf(difname,".nfs%d%d.%s",time(0),i++,name);
      status = nfs_proc_rename(fhandle,name,fhandle,difname);
      if (status != 0) fprintf(stderr,"could not rename %s\n",name);
      nfs_cache_remove(dirp,name);
      nfs_flush_filp(dirp);
      nfs_unlinkatend(difname, fhandle);
      nfsc_put(f);
      
      /* since it will be unlinked we can avoid flushing on close */
      nfsc_or_flags(f,NFSCE_WILLBEGONE); 

      return 0;
    }
  default:
    PR;
    assert(0);
    return 0;
  }
}