⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nfs.c

📁 LFS.This is a kind of file system.
💻 C
📖 第 1 页 / 共 2 页
字号:
      break;    }  nc->reply (nc->getvoidres ());}voidcryptfs::reply_create (nfscall *nc, ptr<lookup3res> lres,		       ptr<getattr3res> ares, clnt_stat stat){  if (stat) {    reply (nc, stat);    return;  }  create3args *argp = nc->template getarg<create3args> ();  diropres3 *resp = nc->template getres<diropres3> ();  authopaque_set (ao, nc->getaup ());  if (!resp->resok->obj.present) {    if (!lres) {      lres = New refcounted<lookup3res>;      call (NFSPROC3_LOOKUP, &argp->where, lres,	    wrap (mkref (this), &cryptfs::reply_create,		  nc, lres, ares), ao);      return;    }    else if (lres->status) {      nc->error (lres->status);      return;    }    resp->resok->obj.set_present (true);    *resp->resok->obj.handle = lres->resok->object;  }  if (!resp->resok->obj_attributes.present) {    if (lres && lres->resok->obj_attributes.present)      resp->resok->obj_attributes = lres->resok->obj_attributes;    else if (!ares) {      ares = New refcounted<getattr3res>;      call (NFSPROC3_GETATTR, &*resp->resok->obj.handle, ares,	    wrap (mkref (this), &cryptfs::reply_create,		  nc, lres, ares), ao);      return;    }    else if (ares->status) {      nc->error (ares->status);      return;    }    else {      resp->resok->obj_attributes.set_present (true);      *resp->resok->obj_attributes.attributes = *ares->attributes;    }  }  if (!resp->resok->obj_attributes.attributes->size)    vNew fhiv (this, *resp->resok->obj.handle,	       &*resp->resok->obj_attributes.attributes);  else    resp->resok->obj_attributes.attributes->size      = fixsize (resp->resok->obj_attributes.attributes->type,		 resp->resok->obj_attributes.attributes->size);  nc->reply (nc->getvoidres ());}voidcryptfs::reply_read (nfscall *nc, clnt_stat stat){  if (stat) {    reply (nc, stat);    return;  }  read3res *res = nc->template getres<read3res> ();  if (res->status || !res->resok->data.size ()) {    reply (nc, stat);    return;  }  read3args *arg = nc->template getarg<read3args> ();  u_int64_t iv;  switch (getiv (arg->file, false, nc->getaup (),		 wrap (mkref (this), &cryptfs::reply_read, nc, stat), &iv)) {  case 0:    return;  case -1:    nc->error (NFS3ERR_IO);    return;  }  rpc_bytes<RPC_INFINITY> data;  swap (res->resok->data, data);  char *p = data.base (), *e = p + (data.size () & ~blockmask);  u_int64_t pos = arg->offset & ~blockmask;  for (; p < e; p += blocksize, pos += blocksize)    decrypt (pos, iv, p, p);  u_int skip = arg->offset & blockmask;  u_int count = data.size ();  if (res->resok->eof && (count & blockmask))    count -= blocksize;  count -= skip;  if (count > arg->count)    count = arg->count;  res->resok->data.set (data.base () + skip, count);  res->resok->count = count;  reply (nc, stat);}voidcryptfs::reply_write (nfscall *nc, u_int64_t end, clnt_stat stat){#ifdef CFSASYNC  if (!stat && !*nc->template getres<nfsstat3> ()      && nc->proc () == NFSPROC3_WRITE)    verf = nc->template getres<write3res> ()->resok->verf;#endif /* CFSASYNC */  if (!stat && !*nc->template getres<nfsstat3> ()      && ((nc->proc () == NFSPROC3_WRITE	   && nc->template getarg<write3args> ()->stable != UNSTABLE)	  || nc->proc () == NFSPROC3_COMMIT))    switch (getiv (*nc->getfh3arg (), true, nc->getaup (),		   wrap (mkref (this), &cryptfs::reply, nc, stat))) {    case -1:      nc->error (NFS3ERR_IO);      return;    case 0:      return;    }  /* Plaintext files that are not a multiple of 16 bytes in length   * have 16 bytes added to ciphertext files.  Thus, while a 16 byte   * file is only 16 bytes, a 15 byte file is actually 31 bytes.   *   * This causes a problem when, for instance, appending one byte to a   * 15 byte file--the resulting ciphertext file will still be 31   * bytes, so the plaintext file will still appear to be 15 bytes.   *   * We must correct the problem by truncating files in this situation.   */  if (nc->proc () == NFSPROC3_WRITE && !(end & blockmask)) {    post_op_attr *poa      = &nc->template getres<write3res> ()->resok->file_wcc.after;    if (!poa->present)      fillpoa (nc, nc->getfh3arg (), poa,	       wrap (this, &cryptfs::reply_write, nc, end));    else if (poa->attributes->size < end + blocksize	     && poa->attributes->size > end) {      setattr3args arg;      arg.object = *nc->getfh3arg ();      arg.new_attributes.size.set_set (true);      *arg.new_attributes.size.val = end;      arg.guard.set_check (true);      *arg.guard.ctime = poa->attributes->ctime;      static wccstat3 garbage;      call (NFSPROC3_SETATTR, &arg, &garbage,	    wrap (mkref (this), &cryptfs::reply, nc), ao);      return;    }  }  reply (nc, stat);}voidcryptfs::reply_write_read (nfscall *nc, ptr<read3res> rres, clnt_stat stat){  if (stat) {    reply (nc, stat);    return;  }  if (rres && rres->status) {    nc->template getres<write3res> ()->set_status (rres->status);    reply (nc, stat);    return;  }  write3args *argp = nc->template getarg<write3args> ();  u_int64_t iv;  switch (getiv (argp->file, false, nc->getaup (),		 wrap (mkref (this), &cryptfs::reply_write_read,		       nc, rres, stat),		 &iv)) {  case 0:    return;  case -1:    nc->error (NFS3ERR_IO);    return;  }  rpc_bytes<RPC_INFINITY> data;  write3args arg = *argp;  u_int64_t offset = arg.offset & ~blockmask;  u_int32_t count = arg.count + (arg.offset & blockmask);  if (count & blockmask) {    if (rres->resok->eof)      count += blocksize;    else      count = count + blockmask & ~blockmask;  }  if (rres) {    data.setsize (count);    bzero (data.base () + data.size () - blocksize, blocksize);    if (rres->resok->data.size () >= blocksize) {      decrypt (offset, iv, data.base (), rres->resok->data.base ());      u_int32_t lastblk = (count & ~blockmask) - blocksize;      if (lastblk + blocksize <= rres->resok->data.size ())	decrypt (offset + lastblk, iv, data.base () + lastblk,		 rres->resok->data.base () + lastblk);    }    memcpy (data.base () + (arg.offset - offset),	    arg.data.base (), arg.data.size ());    swap (data, arg.data);    arg.offset = offset;    arg.count = count;  }  assert (arg.offset == offset && arg.count == count);  for (char *p = arg.data.base (),	 *e = p + (arg.data.size () & ~blockmask);       p < e; p += blocksize, offset += blocksize)    encrypt (offset, iv, p, p);  authopaque_set (ao, nc->getaup ());  call (nc->proc (), &arg, nc->getvoidres (),	wrap (mkref (this), &cryptfs::reply_write, nc,	      argp->offset + argp->count), ao);}voidcryptfs::nfsdispatch (nfscall *nc){  authopaque_set (ao, nc->getaup ());  switch (nc->proc ()) {  case NFSPROC3_LINK:    fixdirop (&nc->template getarg<link3args> ()->link);    break;  case NFSPROC3_RENAME:    fixdirop (&nc->template getarg<rename3args> ()->from);    fixdirop (&nc->template getarg<rename3args> ()->to);    break;  case NFSPROC3_SYMLINK:    {      symlink3args *arg = nc->template getarg<symlink3args> ();      fixdirop (&arg->where);      u_int64_t h;      rnd.getbytes (&h, sizeof (h));      arg->symlink.symlink_data = encodename (0, armor64A (&h, 6)					      << arg->symlink.symlink_data);      break;    }  case NFSPROC3_LOOKUP:  case NFSPROC3_MKDIR:  case NFSPROC3_MKNOD:  case NFSPROC3_REMOVE:  case NFSPROC3_RMDIR:    fixdirop (static_cast<diropargs3 *> (nc->getvoidarg ()));    break;  case NFSPROC3_SETATTR:    {      setattr3args *arg = nc->template getarg<setattr3args> ();      if (arg->new_attributes.size.set) {	*arg->new_attributes.size.val += datashift;	if (*arg->new_attributes.size.val & blockmask)	  *arg->new_attributes.size.val += blocksize;      }      // XXX - need to zero out the file if growing it      break;    }  case NFSPROC3_CREATE:    fixdirop (static_cast<diropargs3 *> (nc->getvoidarg ()));    call (nc->proc (), nc->getvoidarg (), nc->getvoidres (),	  wrap (mkref (this), &cryptfs::reply_create, nc,		ptr<lookup3res> (NULL), ptr<getattr3res> (NULL)),	  ao);    return;  case NFSPROC3_READ:    {      nc->template getarg<read3args> ()->offset += datashift;      read3args arg = *nc->template getarg<read3args> ();      getiv (arg.file, false, nc->getaup ());      arg.count += arg.offset & blockmask;      if (arg.count & blockmask)	arg.count += blocksize;	// More than needed to decrypt, to get eof flag      arg.offset &= ~blockmask;      call (nc->proc (), &arg, nc->getvoidres (),	    wrap (mkref (this), &cryptfs::reply_read, nc), ao);      return;    }  case NFSPROC3_WRITE:    {      // XXX - need to zero out the file if writing beyond end      write3args *arg = nc->template getarg<write3args> ();#ifdef CFSASYNC      arg->stable = UNSTABLE;#endif /* CFSASYNC */      getiv (arg->file, false, nc->getaup ());      arg->offset += datashift;      if (arg->offset & blockmask || arg->count & blockmask) {	read3args rarg;	rarg.file = arg->file;	rarg.offset = arg->offset & ~blockmask;	rarg.count = arg->count + (arg->offset & blockmask);	if (rarg.count & blockmask)	  rarg.count += blocksize; // To get eof flag in read	ref<read3res> rres = New refcounted<read3res>;	call (NFSPROC3_READ, &rarg, rres,	      wrap (mkref (this), &cryptfs::reply_write_read, nc, rres),	      ao);      }      else	reply_write_read (nc, NULL, RPC_SUCCESS);      return;    }  case NFSPROC3_COMMIT:    {#ifdef CFSASYNC      commit3res res (NFS3_OK);      res.resok->verf = verf;      nc->reply (&res);      return;#endif /* CFSASYNC */      commit3args *arg = nc->template getarg<commit3args> ();      arg->offset += datashift;      arg->count += arg->offset & blockmask;      arg->count = arg->count + blockmask & blockmask;      call (nc->proc (), nc->getvoidarg (), nc->getvoidres (),	    wrap (mkref (this), &cryptfs::reply_write,		  nc, arg->offset + arg->count), ao);      return;    }  }  call (nc->proc (), nc->getvoidarg (), nc->getvoidres (),	wrap (mkref (this), &cryptfs::reply, nc), ao);}cryptfs::cryptfs (sfs_aid a, ref<nfsserv> s, clnt_t c, str pwd, int fd)  : nfsc (c), nfss (s), fsfd (fd), aid (a){  char key[sha1::hashsize];  sha1_hash (key, pwd, pwd.len ());  fskey.setkey (key, 16);  bzero (key, sizeof (*key));  nfss->setcb (wrap (this, &cryptfs::nfsdispatch));}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -