示例#1
0
static void
statusrec_fini(struct statusrec *sr)
{

	fattr_free(sr->sr_serverattr);
	fattr_free(sr->sr_clientattr);
	free(sr->sr_file);
}
示例#2
0
static int
statusrec_cook(struct statusrec *sr, char *line)
{
	char *clientattr, *serverattr;

	switch (sr->sr_type) {
	case SR_FILEDEAD:
	case SR_FILELIVE:
		clientattr = proto_get_ascii(&line);
		if (clientattr == NULL || line != NULL)
			return (-1);
		sr->sr_clientattr = fattr_decode(clientattr);
		if (sr->sr_clientattr == NULL)
			return (-1);
		break;
	case SR_DIRDOWN:
		/* Nothing to do. */
		if (line != NULL)
			return (-1);
		break;
	case SR_CHECKOUTLIVE:
		sr->sr_tag = proto_get_ascii(&line);
		sr->sr_date = proto_get_ascii(&line);
		serverattr = proto_get_ascii(&line);
		sr->sr_revnum = proto_get_ascii(&line);
		sr->sr_revdate = proto_get_ascii(&line);
		clientattr = proto_get_ascii(&line);
		if (clientattr == NULL || line != NULL)
			return (-1);
		sr->sr_serverattr = fattr_decode(serverattr);
		if (sr->sr_serverattr == NULL)
			return (-1);
		sr->sr_clientattr = fattr_decode(clientattr);
		if (sr->sr_clientattr == NULL) {
			fattr_free(sr->sr_serverattr);
			return (-1);
		}
		break;
	case SR_CHECKOUTDEAD:
		sr->sr_tag = proto_get_ascii(&line);
		sr->sr_date = proto_get_ascii(&line);
		serverattr = proto_get_ascii(&line);
		if (serverattr == NULL || line != NULL)
			return (-1);
		sr->sr_serverattr = fattr_decode(serverattr);
		if (sr->sr_serverattr == NULL)
			return (-1);
		break;
	case SR_DIRUP:
		clientattr = proto_get_ascii(&line);
		if (clientattr == NULL || line != NULL)
			return (-1);
		sr->sr_clientattr = fattr_decode(clientattr);
		if (sr->sr_clientattr == NULL)
			return (-1);
		break;
	default:
		return (-1);
	}
	return (0);
}
示例#3
0
/*
 * Open the status file.  If scantime is not -1, the file is opened
 * for updating, otherwise, it is opened read-only. If the status file
 * couldn't be opened, NULL is returned and errmsg is set to the error
 * message.
 */
struct status *
status_open(struct coll *coll, time_t scantime, char **errmsg)
{
	struct status *st;
	struct stream *file;
	struct fattr *fa;
	char *destpath, *path;
	int error, rv;

	path = coll_statuspath(coll);
	file = stream_open_file(path, O_RDONLY);
	if (file == NULL) {
		if (errno != ENOENT) {
			xasprintf(errmsg, "Could not open \"%s\": %s\n",
			    path, strerror(errno));
			free(path);
			return (NULL);
		}
		st = status_fromnull(path);
	} else {
		st = status_fromrd(path, file);
		if (st == NULL) {
			xasprintf(errmsg, "Error in \"%s\": Bad header line",
			    path);
			free(path);
			return (NULL);
		}
	}

	if (scantime != -1) {
		/* Open for writing too. */
		xasprintf(&destpath, "%s/%s/%s/", coll->co_base,
		    coll->co_colldir, coll->co_name);
		st->tempfile = tempname(destpath);
		if (mkdirhier(destpath, coll->co_umask) != 0) {
			xasprintf(errmsg, "Cannot create directories leading "
			    "to \"%s\": %s", destpath, strerror(errno));
			free(destpath);
			status_free(st);
			return (NULL);
		}
		free(destpath);
		st->wr = stream_open_file(st->tempfile,
		    O_CREAT | O_TRUNC | O_WRONLY, 0644);
		if (st->wr == NULL) {
			xasprintf(errmsg, "Cannot create \"%s\": %s",
			    st->tempfile, strerror(errno));
			status_free(st);
			return (NULL);
		}
		fa = fattr_new(FT_FILE, -1);
		fattr_mergedefault(fa);
		fattr_umask(fa, coll->co_umask);
		rv = fattr_install(fa, st->tempfile, NULL);
		fattr_free(fa);
		if (rv == -1) {
			xasprintf(errmsg,
			    "Cannot set attributes for \"%s\": %s",
			    st->tempfile, strerror(errno));
			status_free(st);
			return (NULL);
		}
		if (scantime != st->scantime)
			st->dirty = 1;
		error = proto_printf(st->wr, "F %d %t\n", STATUS_VERSION,
		    scantime);
		if (error) {
			st->error = STATUS_ERR_WRITE;
			st->suberror = errno;
			*errmsg = status_errmsg(st);
			status_free(st);
			return (NULL);
		}
	}
	return (st);
}
示例#4
0
文件: dir.c 项目: jgarzik/nfs4d
static bool readdir_iter(DB_TXN *txn, const struct fsdb_de_key *key,
			 size_t key_len, nfsino_t dirent,
			 struct readdir_info *ri)
{
	uint64_t bitmap_out = 0;
	uint32_t dirlen, maxlen;
	struct nfs_fattr_set attr;
	struct nfs_inode *ino = NULL;
	struct list_head *writes = ri->writes;
	struct rpc_write **wr = ri->wr;
	size_t name_len;
	struct nfs_buf de_name;

	if (ri->stop)
		return true;

	if (!ri->cookie_found) {
		if (ri->cookie && (ri->dir_pos <= ri->cookie)) {
			ri->dir_pos++;
			return false;
		}
		ri->cookie_found = true;
	}

	ino = inode_getdec(txn, dirent, 0);
	if (!ino) {
		applog(LOG_WARNING, "           WARNING: inode %016llX not found",
			(unsigned long long) dirent);
		/* FIXME: return via rdattr-error */
		ri->stop = true;
		ri->status = NFS4ERR_NOENT;
		return true;
	}

	memset(&attr, 0, sizeof(attr));

	fattr_fill(ino, &attr);

	name_len = key_len - sizeof(*key);

	dirlen = 8 + 4 + (XDR_QUADLEN(name_len) * 4);
	if (dirlen > ri->dircount) {
		ri->hit_limit = true;
		ri->stop = true;
		if (debugging > 1)
			applog(LOG_DEBUG, "           iter: hit dir limit");
		goto out;
	}

	maxlen = 8 + 4 + (XDR_QUADLEN(name_len) * 4) +
		 16 + fattr_size(&attr) + 4;
	if (maxlen > ri->maxcount) {
		ri->hit_limit = true;
		ri->stop = true;
		if (debugging > 1)
			applog(LOG_DEBUG, "           iter: hit max limit");
		goto out;
	}

	if (ri->first_time) {
		ri->first_time = false;

		/* FIXME: server verifier isn't the best for dir verf */
		WRMEM(&srv.instance_verf, sizeof(verifier4));	/* cookieverf */

		ri->val_follows = WRSKIP(4);
	}

	ri->dircount -= dirlen;
	ri->maxcount -= maxlen;

	/* write value to previous entry4.nextentry */
	*ri->val_follows = htonl(1);
	ri->val_follows = NULL;

	WR64(ri->dir_pos);		/* entry4.cookie */

	de_name.len = name_len;
	de_name.val = (void *) key->name; /* cast is ok: RO data is copied */
	WRBUF(&de_name);		/* entry4.name */

	/* entry4.attrs */
	attr.bitmap = ri->attr_request;
	ri->status = wr_fattr(&attr, &bitmap_out, writes, wr);
	if (ri->status != NFS4_OK)
		ri->stop = true;

	if (debugging)
		applog(LOG_DEBUG, "   READDIR ent: '%.*s' (INO:%016llX MAP:%Lx WRLEN:%u)",
			(int) name_len, key->name,
			(unsigned long long) dirent,
			(unsigned long long) bitmap_out, (*wr)->len);

	ri->val_follows = WRSKIP(4);	/* entry4.nextentry */

	ri->n_results++;
	ri->dir_pos++;

out:
	inode_free(ino);
	fattr_free(&attr);
	if (ri->stop)
		return true;
	return false;
}