コード例 #1
0
int
sli_fcmh_ctor(struct fidc_membh *f, __unusedx int flags)
{
	int rc = 0;

	if (f->fcmh_fg.fg_gen == FGEN_ANY) {
		DEBUG_FCMH(PLL_NOTICE, f, "refusing to open backing file "
		    "with FGEN_ANY");

		/*
		 * This is not an error, we just don't have enough info
		 * to create the backing file.
		 */
		return (0);
	}

	/* try to get a file descriptor for this backing obj */
	rc = sli_open_backing_file(f);
	if (rc == 0) {
		rc = sli_fcmh_getattr(f);
		if (rc)
			DEBUG_FCMH(PLL_WARN, f, "error during "
			    "getattr backing file rc=%d", rc);
	}
	if (!rc)
		f->fcmh_flags |= FCMH_IOD_BACKFILE;
	return (rc);
}
コード例 #2
0
ファイル: fidc_iod.c プロジェクト: pscedu/slash2-stable
int
sli_fcmh_ctor(struct fidc_membh *f, __unusedx int flags)
{
	int rc;
	struct stat stb;
	struct fcmh_iod_info *fii;

	fii = fcmh_2_fii(f);
	INIT_PSC_LISTENTRY(&fii->fii_lentry);

	psc_assert(f->fcmh_flags & FCMH_INITING);
	if (f->fcmh_fg.fg_gen == FGEN_ANY) {
		DEBUG_FCMH(PLL_NOTICE, f, "refusing to open backing file "
		    "with FGEN_ANY");

		/*
		 * This is not an error, we just don't have enough info
		 * to create the backing file.
		 */
		return (0);
	}

	/* try to get a file descriptor for this backing obj */
	rc = sli_open_backing_file(f);
	if (rc == 0) {
		if (fstat(fcmh_2_fd(f), &stb) == -1) {
			rc = -errno;
			DEBUG_FCMH(PLL_WARN, f, "error during "
			    "getattr backing file rc=%d", rc);
			close(fcmh_2_fd(f));
		} else {
			sl_externalize_stat(&stb, &f->fcmh_sstb);
			// XXX get ptruncgen and gen
			f->fcmh_flags |= FCMH_HAVE_ATTRS;
		}
	}
	if (!rc)
		f->fcmh_flags |= FCMH_IOD_BACKFILE;
	return (rc);
}
コード例 #3
0
void
sli_fcmh_dtor(__unusedx struct fidc_membh *f)
{
	if (f->fcmh_flags & FCMH_IOD_BACKFILE) {
		if (close(fcmh_2_fd(f)) == -1) {
			OPSTAT_INCR("close-fail");
			DEBUG_FCMH(PLL_ERROR, f,
			    "dtor/close errno=%d", errno);
		} else
			OPSTAT_INCR("close-succeed");
		psc_rlim_adj(RLIMIT_NOFILE, -1);
		f->fcmh_flags &= ~FCMH_IOD_BACKFILE;
	}
}
コード例 #4
0
ファイル: fidc_iod.c プロジェクト: pscedu/slash2-stable
void
sli_fcmh_dtor(__unusedx struct fidc_membh *f)
{
	struct fcmh_iod_info *fii;

	if (f->fcmh_flags & FCMH_IOD_BACKFILE) {
		if (close(fcmh_2_fd(f)) == -1) {
			OPSTAT_INCR("close-fail");
			DEBUG_FCMH(PLL_ERROR, f,
			    "dtor/close errno=%d", errno);
		} else
			OPSTAT_INCR("close-succeed");
		psc_rlim_adj(RLIMIT_NOFILE, -1);
		f->fcmh_flags &= ~FCMH_IOD_BACKFILE;
	}
	if (f->fcmh_flags & FCMH_IOD_DIRTYFILE) {
		fii = fcmh_2_fii(f);
		lc_remove(&sli_fcmh_dirty, fii);
		f->fcmh_flags &= ~FCMH_IOD_DIRTYFILE;
	}
}
コード例 #5
0
int
slm_fcmh_ctor(struct fidc_membh *f, __unusedx int flags)
{
	struct fcmh_mds_info *fmi;
	struct mio_fh *ino_mfh;
	struct slm_inoh *ih;
	mio_fid_t ino_mfid;
	int rc, vfsid;

	DEBUG_FCMH(PLL_DIAG, f, "ctor");

	rc = slfid_to_vfsid(fcmh_2_fid(f), &vfsid);
	if (rc) {
		DEBUG_FCMH(PLL_WARN, f, "invalid file system ID; "
		    "rc=%d", rc);
		return (rc);
	}
	fmi = fcmh_2_fmi(f);
	memset(fmi, 0, sizeof(*fmi));

	rc = mdsio_lookup_slfid(vfsid, fcmh_2_fid(f), &rootcreds,
	    &f->fcmh_sstb, &fcmh_2_mfid(f));
	if (rc) {
		fmi->fmi_ctor_rc = rc;
		DEBUG_FCMH(PLL_WARN, f, "mdsio_lookup_slfid failed; "
		    "fid="SLPRI_FID" rc=%d",
		    fcmh_2_fid(f), rc);
		return (rc);
	}

	ih = &fmi->fmi_inodeh;
	ih->inoh_flags = INOH_INO_NOTLOADED;

	ino_mfid = fcmh_2_mfid(f);
	ino_mfh = fcmh_2_mfhp(f);

	if (fcmh_isdir(f)) {
		mio_fid_t pmfid;
		char fn[24];

		rc = mdsio_opendir(vfsid, fcmh_2_mfid(f), &rootcreds,
		    NULL, &fcmh_2_mfh(f));
		if (rc) {
			DEBUG_FCMH(PLL_WARN, f, "mdsio_opendir failed; "
			    "mio_fid=%"PRIx64" rc=%d", fcmh_2_mfid(f),
			    rc);
			return (rc);
		}

		snprintf(fn, sizeof(fn), "%016"PRIx64".ino",
		    fcmh_2_fid(f));

		pmfid = mdsio_getfidlinkdir(fcmh_2_fid(f));
		rc = mdsio_lookup(vfsid, pmfid, fn,
		    &fcmh_2_dino_mfid(f), &rootcreds, NULL);
		if (rc == ENOENT) {
			struct slm_inox_od inox;

			rc = mdsio_opencreatef(vfsid, pmfid, &rootcreds,
			    O_CREAT | O_EXCL | O_RDWR,
			    MDSIO_OPENCRF_NOLINK, 0644, fn,
			    &fcmh_2_dino_mfid(f), NULL,
			    &fcmh_2_dino_mfh(f), NULL, NULL, 0);
			psc_assert(rc == 0);

			INOH_LOCK(ih);

			rc = mds_inode_write(vfsid, ih, NULL, NULL);
			psc_assert(rc == 0);

			memset(&inox, 0, sizeof(inox));
			ih->inoh_extras = &inox;
			rc = mds_inox_write(vfsid, ih, NULL, NULL);
			ih->inoh_extras = NULL;

			INOH_ULOCK(ih);

			psc_assert(rc == 0);

			mdsio_release(vfsid, &rootcreds,
			    fcmh_2_dino_mfh(f));
		} else if (rc) {
			fmi->fmi_ctor_rc = rc;
			DEBUG_FCMH(PLL_WARN, f,
			    "mdsio_lookup failed; rc=%d", rc);
			return (rc);
		}

		ino_mfid = fcmh_2_dino_mfid(f);
		ino_mfh = fcmh_2_dino_mfhp(f);
	}

	if (fcmh_isreg(f))
		psc_dynarray_init(&fmi->fmi_ptrunc_clients);

	if (fcmh_isdir(f) || fcmh_isreg(f)) {
		/*
		 * We shouldn't need O_LARGEFILE because SLASH2
		 * metafiles are small.
		 *
		 * I created a file with size of 8070450532247928832
		 * using dd by seeking to a large offset and writing one
		 * byte.  Somehow, the ZFS size becomes 5119601018368.
		 * Without O_LARGEFILE, I got EOVERFLOW (75) here.  The
		 * SLASH2 size is correct though.
		 */
		rc = mdsio_opencreate(vfsid, ino_mfid, &rootcreds,
		    O_RDWR, 0, NULL, NULL, NULL, &ino_mfh->fh, NULL,
		    NULL, 0);
		if (rc == 0) {
			rc = mds_inode_read(&fmi->fmi_inodeh);
			if (rc)
				DEBUG_FCMH(PLL_WARN, f,
				    "could not load inode; "
				    "mfid=%"PRIx64" rc=%d",
				    ino_mfid, rc);
		} else {
			fmi->fmi_ctor_rc = rc;
			DEBUG_FCMH(PLL_WARN, f,
			    "mdsio_opencreate failed; "
			    "mfid=%"PRIx64" rc=%d",
			    ino_mfid, rc);
		}
	} else
		DEBUG_FCMH(PLL_DIAG, f, "special file, no zfs obj");

	return (rc);
}
コード例 #6
0
ファイル: fidc_cli.c プロジェクト: pscedu/slash2-stable
/*
 * Update the high-level app stat(2)-like attribute buffer for a FID
 * cache member.
 * @f: FID cache member to update.
 * @sstb: incoming stat attributes.
 * @flags: behavioral flags.
 * Notes:
 *     (1) if SAVELOCAL has been specified, save local field values:
 *		(o) file size
 *		(o) mtime
 *     (2) This function should only be used by a client.
 */
void
slc_fcmh_setattrf(struct fidc_membh *f, struct srt_stat *sstb,
    int flags)
{
	uidmap_int_stat(sstb);

	if (flags & FCMH_SETATTRF_HAVELOCK)
		FCMH_LOCK_ENSURE(f);
	else
		FCMH_LOCK(f);

	if (fcmh_2_gen(f) == FGEN_ANY)
		fcmh_2_gen(f) = sstb->sst_gen;

	if ((FID_GET_INUM(fcmh_2_fid(f))) != SLFID_ROOT &&
	    fcmh_2_gen(f) > sstb->sst_gen) {
		OPSTAT_INCR("msl.generation-backwards");
		DEBUG_FCMH(PLL_DIAG, f, "attempt to set attr with "
		    "gen %"PRIu64" from old gen %"PRIu64,
		    fcmh_2_gen(f), sstb->sst_gen);
		goto out;
	}

	/*
	 * If we don't have stat attributes, how can we save our local
	 * updates?
	 */
	if ((f->fcmh_flags & FCMH_HAVE_ATTRS) == 0)
		flags |= FCMH_SETATTRF_CLOBBER;

	/*
	 * Always update for roots because we might have faked them
	 * with readdir at the super root.
	 */
	if ((FID_GET_INUM(fcmh_2_fid(f))) == SLFID_ROOT)
		flags |= FCMH_SETATTRF_CLOBBER;

	psc_assert(sstb->sst_gen != FGEN_ANY);
	psc_assert(f->fcmh_fg.fg_fid == sstb->sst_fid);

	/*
	 * The default behavior is to save st_size and st_mtim since we
	 * might have done I/O that the MDS does not know about.
	 */
	if ((flags & FCMH_SETATTRF_CLOBBER) == 0 &&
	    fcmh_isreg(f)) {
		/*
		 * If generation numbers match, take the highest of the
		 * values.  Otherwise, disregard local values and
		 * blindly accept whatever the MDS tells us.
		 */
		if (fcmh_2_ptruncgen(f) == sstb->sst_ptruncgen &&
		    fcmh_2_gen(f) == sstb->sst_gen &&
		    fcmh_2_fsz(f) > sstb->sst_size)
			sstb->sst_size = fcmh_2_fsz(f);
		if (fcmh_2_utimgen(f) == sstb->sst_utimgen)
			sstb->sst_mtim = f->fcmh_sstb.sst_mtim;
	}

	COPY_SSTB(sstb, &f->fcmh_sstb);
	f->fcmh_flags |= FCMH_HAVE_ATTRS;
	f->fcmh_flags &= ~FCMH_GETTING_ATTRS;

	if (sl_fcmh_ops.sfop_postsetattr)
		sl_fcmh_ops.sfop_postsetattr(f);

	DEBUG_FCMH(PLL_DEBUG, f, "attr set");

 out:
	if (!(flags & FCMH_SETATTRF_HAVELOCK))
		FCMH_ULOCK(f);
}
コード例 #7
0
ファイル: fidc_iod.c プロジェクト: pscedu/slash2-stable
/*
 * If the generation number changes, we assume a full truncation has
 * happened.  We need to open a new backing file and attach it to the
 * fcmh.
 */
int
sli_fcmh_reopen(struct fidc_membh *f, slfgen_t fgen)
{
	int rc = 0;

	FCMH_LOCK_ENSURE(f);

	OPSTAT_INCR("reopen");

	if (fgen == FGEN_ANY) {
		OPSTAT_INCR("generation-bogus");
		return (EBADF);
	}
	if (fgen < fcmh_2_gen(f)) {
		OPSTAT_INCR("generation-stale");
		return (ESTALE);
	}

	/*
	 * If our generation number is still unknown try to set it here.
	 */
	if (fcmh_2_gen(f) == FGEN_ANY && fgen != FGEN_ANY) {
		OPSTAT_INCR("generation-fix");
		fcmh_2_gen(f) = fgen;
	}

	if (fgen > fcmh_2_gen(f)) {
		struct sl_fidgen oldfg;
		char fidfn[PATH_MAX];

		DEBUG_FCMH(PLL_DIAG, f, "reopening new backing file");
		OPSTAT_INCR("slvr-remove-reopen");
		slvr_remove_all(f);

		/*
		 * It's possible the pruning of all slivers and bmaps
		 * ended up fcmh_op_done() our fcmh so ensure it is
		 * locked upon finishing.
		 */
		FCMH_RLOCK(f);

		/*
		 * Need to reopen the backing file and possibly remove
		 * the old one.
		 */
		if (f->fcmh_flags & FCMH_IOD_BACKFILE) {
			if (close(fcmh_2_fd(f)) == -1) {
				OPSTAT_INCR("close-fail");
				DEBUG_FCMH(PLL_ERROR, f,
				    "reopen/close errno=%d", errno);
			} else {
				OPSTAT_INCR("close-succeed");
			}
			fcmh_2_fd(f) = -1;
			psc_rlim_adj(RLIMIT_NOFILE, -1);
			f->fcmh_flags &= ~FCMH_IOD_BACKFILE;
		}

		oldfg.fg_fid = fcmh_2_fid(f);
		oldfg.fg_gen = fcmh_2_gen(f);

		fcmh_2_gen(f) = fgen;

		rc = sli_open_backing_file(f);
		/* Notify upper layers that open() has failed. */
		if (!rc)
			f->fcmh_flags |= FCMH_IOD_BACKFILE;

		/* Do some upfront garbage collection. */
		sli_fg_makepath(&oldfg, fidfn);

		errno = 0;
		unlink(fidfn);
		DEBUG_FCMH(PLL_INFO, f, "upfront unlink(), errno=%d",
		    errno);

	} else if (!(f->fcmh_flags & FCMH_IOD_BACKFILE)) {

		rc = sli_open_backing_file(f);
		if (!rc)
			f->fcmh_flags |= FCMH_IOD_BACKFILE;
		OPSTAT_INCR("generation-same");
	}
	return (rc);
}