Beispiel #1
0
struct inode *nfs_fhget(struct super_block *sb, struct nfs_fh *fhandle,
			struct nfs_fattr *fattr)
{
	struct nfs_fattr newfattr;
	int error;
	struct inode *inode;

	if (!sb) {
		printk("nfs_fhget: super block is NULL\n");
		return NULL;
	}
	if (!fattr) {
		error = nfs_proc_getattr(&sb->u.nfs_sb.s_server, fhandle,
			&newfattr);
		if (error) {
			printk("nfs_fhget: getattr error = %d\n", -error);
			return NULL;
		}
		fattr = &newfattr;
	}
	if (!(inode = iget(sb, fattr->fileid))) {
		printk("nfs_fhget: iget failed\n");
		return NULL;
	}
	if (inode->i_dev == sb->s_dev) {
		if (inode->i_ino != fattr->fileid) {
			printk("nfs_fhget: unexpected inode from iget\n");
			return inode;
		}
		*NFS_FH(inode) = *fhandle;
		nfs_refresh_inode(inode, fattr);
	}
	return inode;
}
Beispiel #2
0
int
nfs_chmod(struct file *filp, mode_t mode) {
  struct nfs_fh *fhandle;
  struct nfs_fattr temp_fattr;
  struct nfs_sattr temp_sattr;

  int status;

  DPRINTF(CLU_LEVEL,("nfs_chmod:\n"));
  demand(filp, bogus filp);

  fhandle = GETFHANDLE(filp);

  k2printf("nfs_chmod: nfs_proc_getattr\n");
  status = nfs_proc_getattr(fhandle,&temp_fattr);

  if (status == 0) {

    /* ALLPERMS is  07777 */
    temp_sattr.mode = ((temp_fattr.mode & ~ALLPERMS) |  (mode & ALLPERMS)); 

    DPRINTF(CLU_LEVEL,("nfs_chmod: nfs_proc_getattr returned %d, "
		       "new mode %08x, old %08x, setmode: %08x\n",
		       status,mode,temp_fattr.mode,temp_sattr.mode));
    /* do only permissions, also should use macro definitions */
    temp_sattr.uid  = -1; 
    temp_sattr.gid  = -1; 
    temp_sattr.size = -1; 
    temp_sattr.atime.seconds  = -1;
    temp_sattr.atime.useconds = -1;
    temp_sattr.mtime.seconds  = -1;
    temp_sattr.mtime.useconds = -1;
    
    status = nfs_proc_setattr(fhandle,
			      &temp_sattr,
			      &temp_fattr);

    DPRINTF(CLU_LEVEL,("nfs_chmod: nfs_proc_setattr returned %d\n",status));
    if (status == 0) {
      filp->f_mode = temp_sattr.mode;
      nfs_fill_stat(&temp_fattr, GETNFSCE(filp));
    }

    return(status);}
  else {
    fprintf(stderr,"warning: nfs_chmod, was not able to do getattr\n"
	   "on a NFS filp\n");
    errno = EACCES;
    return -1;
  }

}
Beispiel #3
0
int
nfs_truncate(struct file *filp, off_t length) {
  struct nfs_fh *fhandle;
  struct nfs_fattr temp_fattr;
  struct nfs_sattr temp_sattr;

  int status;
  /* make sure you interact with bc to drop unneeded page */
  DPRINTF(CLU_LEVEL,("nfs_truncate:\n"));
  demand(filp, bogus filp);

  fhandle = GETFHANDLE(filp);
  
  /* HBXX this is OVERKILL, should not flush all things. */
  nfsc_sync(GETNFSCE(filp));	/* just to be sure the size if proper */

  k2printf("nfs_truncate: nfs_proc_getattr\n");
  status = nfs_proc_getattr(fhandle,&temp_fattr);

  if (status == 0) {
    temp_sattr.mode = temp_fattr.mode;
    /* do only permissions, also should use macro definitions */
    temp_sattr.uid  = -1;
    temp_sattr.gid  = -1;
    temp_sattr.size = length;
    temp_sattr.atime.seconds  = -1;
    temp_sattr.atime.useconds = -1;
    temp_sattr.mtime.seconds  = -1;
    temp_sattr.mtime.useconds = -1;
    
    status = nfs_proc_setattr(fhandle,
			      &temp_sattr,
			      &temp_fattr);

    if (status == 0) {
      /* note that the f_pos is not changed */
      nfs_flush_filp(filp);
      nfs_fill_stat(&temp_fattr, GETNFSCE(filp));
      return(0);
    }
    errno = status;
    return(-1);
  } else {
    fprintf(stderr,"warning: nfs_truncate, was not able to do getattr\n"
	   "on a NFS filp\n");
    errno = status;
    return -1;
  }
}
Beispiel #4
0
int 
nfs_mkdir(struct file *dir_filp, const char *name, mode_t mode) {
  struct nfs_fh *dhandle, temp_fhandle;
  struct nfs_fattr temp_fattr;
  struct nfs_sattr temp_sattr;
  int status;

  DPRINTF(CLU_LEVEL,("nfs_mkdir:\n"));
  demand(dir_filp, bogus dir_filp);
  demand(name, empty name given to nfs_mkdir);

  dhandle = GETFHANDLE(dir_filp);

  k2printf("nfs_mkdir: nfs_proc_getattr\n");
  status = nfs_proc_getattr(dhandle,&temp_fattr);

  if (status != 0) {
    fprintf(stderr,"nfs_mkdir, was not able to do getattr\n"
	     "on a NFS filp\n");
      errno = status;
      return -1;
  }
  
  temp_sattr.mode = ((temp_fattr.mode & 0xfffffe00) | (mode & 0x000001ff));
  temp_sattr.uid  = __current->uid;
  temp_sattr.gid  = (temp_fattr.gid) ? temp_fattr.gid : __current->egid;
  temp_sattr.size = 1024;
  temp_sattr.atime.seconds  = -1;
  temp_sattr.atime.useconds = -1;
  temp_sattr.mtime.seconds  = -1;
  temp_sattr.mtime.useconds = -1;
  status = nfs_proc_mkdir(dhandle,
			  name,
			  &temp_sattr,
			  &temp_fhandle,
			  &temp_fattr);
  
  
  nfs_flush_filp(dir_filp);
  nfs_cache_remove(dir_filp,name);
  if (status == 0) {
    nfs_cache_add_devino(FHGETDEV(dhandle),temp_fattr.fileid,"..", 
			 GETNFSCE(dir_filp));
    return 0;
  } else {
    errno = status; return -1;
  }
}
Beispiel #5
0
int
nfs_chown(struct file *filp, uid_t owner, gid_t group) {
  struct nfs_fh *fhandle;
  struct nfs_fattr temp_fattr;
  struct nfs_sattr temp_sattr;

  int status;

  kprintf("nfs_chown: bogusly returning success for ease of use.\n");
  return 0; /* XXX */

  DPRINTF(CLU_LEVEL,("nfs_chown:\n"));
  demand(filp, bogus filp);

  fhandle = GETFHANDLE(filp);
#if 0
  k2printf("nfs_chown: nfs_proc_getattr\n");
  status = nfs_proc_getattr(fhandle,&temp_fattr);
#else
  status = 0;
#endif
  if (status == 0) {
    temp_sattr.mode = -1;
    temp_sattr.uid  = (owner == -1) ? -1 : owner;
    temp_sattr.gid  = (group == -1) ? -1 : group;
    temp_sattr.size = -1;
    temp_sattr.atime.seconds  = -1;
    temp_sattr.atime.useconds = -1;
    temp_sattr.mtime.seconds  = -1;
    temp_sattr.mtime.useconds = -1;
    
    status = nfs_proc_setattr(
			      fhandle,
			      &temp_sattr,
			      &temp_fattr);
    if (status == 0) {
      nfs_fill_stat(&temp_fattr, GETNFSCE(filp));
    }
    return(status);}
  else {
    fprintf(stderr,"nfs_chown, was not able to do getattr\n"
	     "on a NFS filp\n");
      errno = EACCES;
      return -1;
  }
  
}
Beispiel #6
0
inline int
nfs_stat_fh(struct nfs_fh *fhandle, nfsc_p e) {
  struct nfs_fattr temp_fattr;
  int status;

  k2printf("nfs_stat_fh : nfs_proc_getattr\n");
  status = nfs_proc_getattr(fhandle,&temp_fattr);
    
  if (status != 0) {
    k1printf("nfs_stat_fh, was not able to do getattr\n"
	     "on a NFS filp status: %d\n",status);
    errno = status;
    return -1;
  }
  nfs_fill_stat(&temp_fattr, e);
  return(0);

}
Beispiel #7
0
static inline void revalidate_dir(struct nfs_server * server, struct inode * dir)
{
	struct nfs_fattr fattr;

	if (jiffies - NFS_READTIME(dir) < NFS_ATTRTIMEO(dir))
		return;

	NFS_READTIME(dir) = jiffies;
	if (nfs_proc_getattr(server, NFS_FH(dir), &fattr) == 0) {
		nfs_refresh_inode(dir, &fattr);
		if (fattr.mtime.seconds == NFS_OLDMTIME(dir)) {
			if ((NFS_ATTRTIMEO(dir) <<= 1) > server->acdirmax)
				NFS_ATTRTIMEO(dir) = server->acdirmax;
			return;
		}
		NFS_OLDMTIME(dir) = fattr.mtime.seconds;
	}
	/* invalidate directory cache here when we _really_ start caching */
}
Beispiel #8
0
/*
 * The way this works is that the mount process passes a structure
 * in the data argument which contains the server's IP address
 * and the root file handle obtained from the server's mount
 * daemon. We stash these away in the private superblock fields.
 */
struct super_block *
nfs_read_super(struct super_block *sb, void *raw_data, int silent)
{
    struct nfs_mount_data	*data = (struct nfs_mount_data *) raw_data;
    struct nfs_server	*server;
    struct rpc_xprt		*xprt;
    struct rpc_clnt		*clnt;
    struct nfs_fh		*root_fh;
    struct inode		*root_inode;
    unsigned int		authflavor;
    int			tcp;
    struct sockaddr_in	srvaddr;
    struct rpc_timeout	timeparms;
    struct nfs_fattr	fattr;

    MOD_INC_USE_COUNT;
    if (!data)
        goto out_miss_args;

    /* No NFS V3. */
    if (data->flags & NFS_MOUNT_VER3)
        goto out_fail;

    /* Don't complain if "mount" is newer. */
    if (data->version < NFS_MOUNT_VERSION) {
        printk("nfs warning: mount version %s than kernel\n",
               data->version < NFS_MOUNT_VERSION ? "older" : "newer");
        if (data->version < 2)
            data->namlen = 0;
        if (data->version < 3)
            data->bsize  = 0;
    }

    /* We now require that the mount process passes the remote address */
    memcpy(&srvaddr, &data->addr, sizeof(srvaddr));
    if (srvaddr.sin_addr.s_addr == INADDR_ANY)
        goto out_no_remote;

    lock_super(sb);

    sb->s_flags |= MS_ODD_RENAME; /* This should go away */

    sb->s_magic      = NFS_SUPER_MAGIC;
    sb->s_op         = &nfs_sops;
    sb->s_blocksize  = nfs_block_size(data->bsize, &sb->s_blocksize_bits);
    sb->u.nfs_sb.s_root = data->root;
    server           = &sb->u.nfs_sb.s_server;
    server->rsize    = nfs_block_size(data->rsize, NULL);
    server->wsize    = nfs_block_size(data->wsize, NULL);
    server->flags    = data->flags;

    if (data->flags & NFS_MOUNT_NOAC) {
        data->acregmin = data->acregmax = 0;
        data->acdirmin = data->acdirmax = 0;
    }
    server->acregmin = data->acregmin*HZ;
    server->acregmax = data->acregmax*HZ;
    server->acdirmin = data->acdirmin*HZ;
    server->acdirmax = data->acdirmax*HZ;

    server->hostname = kmalloc(strlen(data->hostname) + 1, GFP_KERNEL);
    if (!server->hostname)
        goto out_unlock;
    strcpy(server->hostname, data->hostname);

    /* Which protocol do we use? */
    tcp   = (data->flags & NFS_MOUNT_TCP);

    /* Initialize timeout values */
    timeparms.to_initval = data->timeo * HZ / 10;
    timeparms.to_retries = data->retrans;
    timeparms.to_maxval  = tcp? RPC_MAX_TCP_TIMEOUT : RPC_MAX_UDP_TIMEOUT;
    timeparms.to_exponential = 1;

    /* Now create transport and client */
    xprt = xprt_create_proto(tcp? IPPROTO_TCP : IPPROTO_UDP,
                             &srvaddr, &timeparms);
    if (xprt == NULL)
        goto out_no_xprt;

    /* Choose authentication flavor */
    authflavor = RPC_AUTH_UNIX;
    if (data->flags & NFS_MOUNT_SECURE)
        authflavor = RPC_AUTH_DES;
    else if (data->flags & NFS_MOUNT_KERBEROS)
        authflavor = RPC_AUTH_KRB;

    clnt = rpc_create_client(xprt, server->hostname, &nfs_program,
                             NFS_VERSION, authflavor);
    if (clnt == NULL)
        goto out_no_client;

    clnt->cl_intr     = (data->flags & NFS_MOUNT_INTR)? 1 : 0;
    clnt->cl_softrtry = (data->flags & NFS_MOUNT_SOFT)? 1 : 0;
    clnt->cl_chatty   = 1;
    server->client    = clnt;

    /* Fire up rpciod if not yet running */
    if (rpciod_up() != 0)
        goto out_no_iod;

    /*
     * Keep the super block locked while we try to get
     * the root fh attributes.
     */
    root_fh = kmalloc(sizeof(struct nfs_fh), GFP_KERNEL);
    if (!root_fh)
        goto out_no_fh;
    *root_fh = data->root;

    if (nfs_proc_getattr(server, root_fh, &fattr) != 0)
        goto out_no_fattr;

    clnt->cl_to_err = 1;

    root_inode = __nfs_fhget(sb, &fattr);
    if (!root_inode)
        goto out_no_root;
    sb->s_root = d_alloc_root(root_inode, NULL);
    if (!sb->s_root)
        goto out_no_root;
    sb->s_root->d_op = &nfs_dentry_operations;
    sb->s_root->d_fsdata = root_fh;

    /* We're airborne */
    unlock_super(sb);

    /* Check whether to start the lockd process */
    if (!(server->flags & NFS_MOUNT_NONLM))
        lockd_up();
    return sb;

    /* Yargs. It didn't work out. */
out_no_root:
    printk("nfs_read_super: get root inode failed\n");
    iput(root_inode);
    goto out_free_fh;

out_no_fattr:
    printk("nfs_read_super: get root fattr failed\n");
out_free_fh:
    kfree(root_fh);
out_no_fh:
    rpciod_down();
    goto out_shutdown;

out_no_iod:
    printk(KERN_WARNING "NFS: couldn't start rpciod!\n");
out_shutdown:
    rpc_shutdown_client(server->client);
    goto out_free_host;

out_no_client:
    printk(KERN_WARNING "NFS: cannot create RPC client.\n");
    xprt_destroy(xprt);
    goto out_free_host;

out_no_xprt:
    printk(KERN_WARNING "NFS: cannot create RPC transport.\n");

out_free_host:
    kfree(server->hostname);
out_unlock:
    unlock_super(sb);
    goto out_fail;

out_no_remote:
    printk("NFS: mount program didn't pass remote address!\n");
    goto out_fail;

out_miss_args:
    printk("nfs_read_super: missing data argument\n");

out_fail:
    sb->s_dev = 0;
    MOD_DEC_USE_COUNT;
    return NULL;
}
Beispiel #9
0
int
nfs_utimes(struct file *filp, const struct timeval *times) {
  struct nfs_fh *fhandle;
  struct nfs_fattr temp_fattr;
  struct nfs_sattr temp_sattr;

  int status;

  DPRINTF(CLU_LEVEL,("nfs_utimes:\n"));
  demand(filp, bogus filp);

  fhandle = GETFHANDLE(filp);
#if 0
  fprintf(stderr,"nfs_utimes: nfs_proc_getattr\n");
  status = nfs_proc_getattr(fhandle,&temp_fattr);
#else
  status = 0;
#endif
  if (status == 0) {
    temp_sattr.mode = -1;
    temp_sattr.uid  = -1;
    temp_sattr.gid  = -1;
    temp_sattr.size = -1;

    if (times) {
      //fprintf(stderr,"time passed in\n");
      temp_sattr.atime.seconds  = times[0].tv_sec;
      temp_sattr.atime.useconds = times[0].tv_usec;
      temp_sattr.mtime.seconds  = times[1].tv_sec;
      temp_sattr.mtime.useconds = times[1].tv_usec;
    } else {
      struct timeval times2;
      gettimeofday(&times2,(struct timezone *)0);
      //fprintf(stderr,"times2.tv_sec = %ld\n",times2.tv_sec);
      temp_sattr.atime.seconds  = times2.tv_sec;
      temp_sattr.atime.useconds = times2.tv_usec;
      temp_sattr.mtime.seconds  = times2.tv_sec;
      temp_sattr.mtime.useconds = times2.tv_usec;
    }
    /* the owner will be the only one allowed to change the file */
    status = nfs_proc_setattr(fhandle,
			      &temp_sattr,
			      &temp_fattr);

    //fprintf(stderr,"status: %d errno %d\n",status,errno);
    if (status == 0) {
      nfsc_p e = GETNFSCE(filp);
      nfs_fill_stat(&temp_fattr,e);
      nfs_flush_filp(filp);
    }

    
    return(status);
  } else {
    fprintf(stderr,"warning: nfs_utimes, was not able to do getattr\n"
	   "on a NFS filp\n");
    errno = EACCES;
    return -1;
  }

}