/* * There can be up to 512 directory entries. Each entry is encoded as * follows: * 4 bytes: string size (n) * n bytes: string * 1 byte: trailing zero * padding to 8 bytes * 16 bytes: khandle * padding to 8 bytes * * The trailer_buf starts with a struct orangefs_readdir_response_s * which must be skipped to get to the directory data. * * The data which is received from the userspace daemon is termed a * part and is stored in a linked list in case more than one part is * needed for a large directory. * * The position pointer (ctx->pos) encodes the part and offset on which * to begin reading at. Bits above PART_SHIFT encode the part and bits * below PART_SHIFT encode the offset. Parts are stored in a linked * list which grows as data is received from the server. The overhead * associated with managing the list is presumed to be small compared to * the overhead of communicating with the server. * * As data is received from the server, it is placed at the end of the * part list. Data is parsed from the current position as it is needed. * When data is determined to be corrupt, it is either because the * userspace component has sent back corrupt data or because the file * pointer has been moved to an invalid location. Since the two cannot * be differentiated, return EIO. * * Part zero is synthesized to contains `.' and `..'. Part one is the * first part of the part list.
*/
/* * Despite the badly named field, readdir does not use shared * memory. However, there are a limited number of readdir * slots, which must be allocated here. This flag simply tells * the op scheduler to return the op here for retry.
*/
op->uses_shared_memory = 1;
op->upcall.req.readdir.refn = oi->refn;
op->upcall.req.readdir.token = od->token;
op->upcall.req.readdir.max_dirent_count =
ORANGEFS_MAX_DIRENT_COUNT_READDIR;
/* * The maximum size is size per entry times the 512 entries plus * the header. This is well under the limit.
*/ if (op->downcall.trailer_size > PART_SIZE) {
vfree(op->downcall.trailer_buf);
od->error = -EIO; return -EIO;
}
part = od->part; while (part->next && count) {
count--;
part = part->next;
} /* This means the userspace file offset is invalid. */ if (count) {
od->error = -EIO; return -EIO;
}
while (part && part->len) { int r;
r = fill_from_part(part, ctx); if (r < 0) {
od->error = r; return r;
} elseif (r == 0) { /* Userspace buffer is full. */ break;
} else { /* * The part ran out of data. Move to the next
* part. */
ctx->pos = (ctx->pos & PART_MASK) +
(1 << PART_SHIFT);
part = part->next;
}
} return 0;
}
static loff_t orangefs_dir_llseek(struct file *file, loff_t offset, int whence)
{ struct orangefs_dir *od = file->private_data; /* * Delete the stored data so userspace sees new directory * entries.
*/ if (!whence && offset < od->end) { struct orangefs_dir_part *part = od->part; while (part) { struct orangefs_dir_part *next = part->next;
vfree(part);
part = next;
}
od->token = ORANGEFS_ITERATE_START;
od->part = NULL;
od->end = 1 << PART_SHIFT;
} return default_llseek(file, offset, whence);
}
if (ctx->pos == 0) { if (!dir_emit_dot(file, ctx)) return 0;
ctx->pos++;
} if (ctx->pos == 1) { if (!dir_emit_dotdot(file, ctx)) return 0;
ctx->pos = 1 << PART_SHIFT;
}
/* * The seek position is in the first synthesized part but is not * valid.
*/ if ((ctx->pos & PART_MASK) == 0) return -EIO;
r = 0;
/* * Must read more if the user has sought past what has been read * so far. Stop a user who has sought past the end.
*/ while (od->token != ORANGEFS_ITERATE_END &&
ctx->pos > od->end) {
r = orangefs_dir_more(od, inode); if (r) return r;
} if (od->token == ORANGEFS_ITERATE_END && ctx->pos > od->end) return -EIO;
/* Then try to fill if there's any left in the buffer. */ if (ctx->pos < od->end) {
r = orangefs_dir_fill(od, ctx); if (r) return r;
}
/* Finally get some more and try to fill. */ if (od->token != ORANGEFS_ITERATE_END) {
r = orangefs_dir_more(od, inode); if (r) return r;
r = orangefs_dir_fill(od, ctx);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.