dir.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright 2017 Omnibond Systems, L.L.C.
  4. */
  5. #include <linux/filelock.h>
  6. #include "protocol.h"
  7. #include "orangefs-kernel.h"
  8. #include "orangefs-bufmap.h"
  9. struct orangefs_dir_part {
  10. struct orangefs_dir_part *next;
  11. size_t len;
  12. };
  13. struct orangefs_dir {
  14. __u64 token;
  15. struct orangefs_dir_part *part;
  16. loff_t end;
  17. int error;
  18. };
  19. #define PART_SHIFT (24)
  20. #define PART_SIZE (1<<24)
  21. #define PART_MASK (~(PART_SIZE - 1))
  22. /*
  23. * There can be up to 512 directory entries. Each entry is encoded as
  24. * follows:
  25. * 4 bytes: string size (n)
  26. * n bytes: string
  27. * 1 byte: trailing zero
  28. * padding to 8 bytes
  29. * 16 bytes: khandle
  30. * padding to 8 bytes
  31. *
  32. * The trailer_buf starts with a struct orangefs_readdir_response_s
  33. * which must be skipped to get to the directory data.
  34. *
  35. * The data which is received from the userspace daemon is termed a
  36. * part and is stored in a linked list in case more than one part is
  37. * needed for a large directory.
  38. *
  39. * The position pointer (ctx->pos) encodes the part and offset on which
  40. * to begin reading at. Bits above PART_SHIFT encode the part and bits
  41. * below PART_SHIFT encode the offset. Parts are stored in a linked
  42. * list which grows as data is received from the server. The overhead
  43. * associated with managing the list is presumed to be small compared to
  44. * the overhead of communicating with the server.
  45. *
  46. * As data is received from the server, it is placed at the end of the
  47. * part list. Data is parsed from the current position as it is needed.
  48. * When data is determined to be corrupt, it is either because the
  49. * userspace component has sent back corrupt data or because the file
  50. * pointer has been moved to an invalid location. Since the two cannot
  51. * be differentiated, return EIO.
  52. *
  53. * Part zero is synthesized to contains `.' and `..'. Part one is the
  54. * first part of the part list.
  55. */
  56. static int do_readdir(struct orangefs_dir *od, struct inode *inode,
  57. struct orangefs_kernel_op_s *op)
  58. {
  59. struct orangefs_inode_s *oi = ORANGEFS_I(inode);
  60. struct orangefs_readdir_response_s *resp;
  61. int bufi, r;
  62. /*
  63. * Despite the badly named field, readdir does not use shared
  64. * memory. However, there are a limited number of readdir
  65. * slots, which must be allocated here. This flag simply tells
  66. * the op scheduler to return the op here for retry.
  67. */
  68. op->uses_shared_memory = 1;
  69. op->upcall.req.readdir.refn = oi->refn;
  70. op->upcall.req.readdir.token = od->token;
  71. op->upcall.req.readdir.max_dirent_count =
  72. ORANGEFS_MAX_DIRENT_COUNT_READDIR;
  73. again:
  74. bufi = orangefs_readdir_index_get();
  75. if (bufi < 0) {
  76. od->error = bufi;
  77. return bufi;
  78. }
  79. op->upcall.req.readdir.buf_index = bufi;
  80. r = service_operation(op, "orangefs_readdir",
  81. get_interruptible_flag(inode));
  82. orangefs_readdir_index_put(bufi);
  83. if (op_state_purged(op)) {
  84. if (r == -EAGAIN) {
  85. vfree(op->downcall.trailer_buf);
  86. goto again;
  87. } else if (r == -EIO) {
  88. vfree(op->downcall.trailer_buf);
  89. od->error = r;
  90. return r;
  91. }
  92. }
  93. if (r < 0) {
  94. vfree(op->downcall.trailer_buf);
  95. od->error = r;
  96. return r;
  97. } else if (op->downcall.status) {
  98. vfree(op->downcall.trailer_buf);
  99. od->error = op->downcall.status;
  100. return op->downcall.status;
  101. }
  102. /*
  103. * The maximum size is size per entry times the 512 entries plus
  104. * the header. This is well under the limit.
  105. */
  106. if (op->downcall.trailer_size > PART_SIZE) {
  107. vfree(op->downcall.trailer_buf);
  108. od->error = -EIO;
  109. return -EIO;
  110. }
  111. resp = (struct orangefs_readdir_response_s *)
  112. op->downcall.trailer_buf;
  113. od->token = resp->token;
  114. return 0;
  115. }
  116. static int parse_readdir(struct orangefs_dir *od,
  117. struct orangefs_kernel_op_s *op)
  118. {
  119. struct orangefs_dir_part *part, *new;
  120. size_t count;
  121. count = 1;
  122. part = od->part;
  123. while (part) {
  124. count++;
  125. if (part->next)
  126. part = part->next;
  127. else
  128. break;
  129. }
  130. new = (void *)op->downcall.trailer_buf;
  131. new->next = NULL;
  132. new->len = op->downcall.trailer_size -
  133. sizeof(struct orangefs_readdir_response_s);
  134. if (!od->part)
  135. od->part = new;
  136. else
  137. part->next = new;
  138. count++;
  139. od->end = count << PART_SHIFT;
  140. return 0;
  141. }
  142. static int orangefs_dir_more(struct orangefs_dir *od, struct inode *inode)
  143. {
  144. struct orangefs_kernel_op_s *op;
  145. int r;
  146. op = op_alloc(ORANGEFS_VFS_OP_READDIR);
  147. if (!op) {
  148. od->error = -ENOMEM;
  149. return -ENOMEM;
  150. }
  151. r = do_readdir(od, inode, op);
  152. if (r) {
  153. od->error = r;
  154. goto out;
  155. }
  156. r = parse_readdir(od, op);
  157. if (r) {
  158. od->error = r;
  159. goto out;
  160. }
  161. od->error = 0;
  162. out:
  163. op_release(op);
  164. return od->error;
  165. }
  166. static int fill_from_part(struct orangefs_dir_part *part,
  167. struct dir_context *ctx)
  168. {
  169. const int offset = sizeof(struct orangefs_readdir_response_s);
  170. struct orangefs_khandle *khandle;
  171. __u32 *len, padlen;
  172. loff_t i;
  173. char *s;
  174. i = ctx->pos & ~PART_MASK;
  175. /* The file offset from userspace is too large. */
  176. if (i > part->len)
  177. return 1;
  178. /*
  179. * If the seek pointer is positioned just before an entry it
  180. * should find the next entry.
  181. */
  182. if (i % 8)
  183. i = i + (8 - i%8)%8;
  184. while (i < part->len) {
  185. if (part->len < i + sizeof *len)
  186. break;
  187. len = (void *)part + offset + i;
  188. /*
  189. * len is the size of the string itself. padlen is the
  190. * total size of the encoded string.
  191. */
  192. padlen = (sizeof *len + *len + 1) +
  193. (8 - (sizeof *len + *len + 1)%8)%8;
  194. if (part->len < i + padlen + sizeof *khandle)
  195. goto next;
  196. s = (void *)part + offset + i + sizeof *len;
  197. if (s[*len] != 0)
  198. goto next;
  199. khandle = (void *)part + offset + i + padlen;
  200. if (!dir_emit(ctx, s, *len,
  201. orangefs_khandle_to_ino(khandle),
  202. DT_UNKNOWN))
  203. return 0;
  204. i += padlen + sizeof *khandle;
  205. i = i + (8 - i%8)%8;
  206. BUG_ON(i > part->len);
  207. ctx->pos = (ctx->pos & PART_MASK) | i;
  208. continue;
  209. next:
  210. i += 8;
  211. }
  212. return 1;
  213. }
  214. static int orangefs_dir_fill(struct orangefs_dir *od, struct dir_context *ctx)
  215. {
  216. struct orangefs_dir_part *part;
  217. size_t count;
  218. count = ((ctx->pos & PART_MASK) >> PART_SHIFT) - 1;
  219. part = od->part;
  220. while (part->next && count) {
  221. count--;
  222. part = part->next;
  223. }
  224. /* This means the userspace file offset is invalid. */
  225. if (count) {
  226. od->error = -EIO;
  227. return -EIO;
  228. }
  229. while (part && part->len) {
  230. int r;
  231. r = fill_from_part(part, ctx);
  232. if (r < 0) {
  233. od->error = r;
  234. return r;
  235. } else if (r == 0) {
  236. /* Userspace buffer is full. */
  237. break;
  238. } else {
  239. /*
  240. * The part ran out of data. Move to the next
  241. * part. */
  242. ctx->pos = (ctx->pos & PART_MASK) +
  243. (1 << PART_SHIFT);
  244. part = part->next;
  245. }
  246. }
  247. return 0;
  248. }
  249. static loff_t orangefs_dir_llseek(struct file *file, loff_t offset,
  250. int whence)
  251. {
  252. struct orangefs_dir *od = file->private_data;
  253. /*
  254. * Delete the stored data so userspace sees new directory
  255. * entries.
  256. */
  257. if (!whence && offset < od->end) {
  258. struct orangefs_dir_part *part = od->part;
  259. while (part) {
  260. struct orangefs_dir_part *next = part->next;
  261. vfree(part);
  262. part = next;
  263. }
  264. od->token = ORANGEFS_ITERATE_START;
  265. od->part = NULL;
  266. od->end = 1 << PART_SHIFT;
  267. }
  268. return default_llseek(file, offset, whence);
  269. }
  270. static int orangefs_dir_iterate(struct file *file,
  271. struct dir_context *ctx)
  272. {
  273. struct orangefs_dir *od = file->private_data;
  274. struct inode *inode = file_inode(file);
  275. int r;
  276. if (od->error)
  277. return od->error;
  278. if (ctx->pos == 0) {
  279. if (!dir_emit_dot(file, ctx))
  280. return 0;
  281. ctx->pos++;
  282. }
  283. if (ctx->pos == 1) {
  284. if (!dir_emit_dotdot(file, ctx))
  285. return 0;
  286. ctx->pos = 1 << PART_SHIFT;
  287. }
  288. /*
  289. * The seek position is in the first synthesized part but is not
  290. * valid.
  291. */
  292. if ((ctx->pos & PART_MASK) == 0)
  293. return -EIO;
  294. r = 0;
  295. /*
  296. * Must read more if the user has sought past what has been read
  297. * so far. Stop a user who has sought past the end.
  298. */
  299. while (od->token != ORANGEFS_ITERATE_END &&
  300. ctx->pos > od->end) {
  301. r = orangefs_dir_more(od, inode);
  302. if (r)
  303. return r;
  304. }
  305. if (od->token == ORANGEFS_ITERATE_END && ctx->pos > od->end)
  306. return -EIO;
  307. /* Then try to fill if there's any left in the buffer. */
  308. if (ctx->pos < od->end) {
  309. r = orangefs_dir_fill(od, ctx);
  310. if (r)
  311. return r;
  312. }
  313. /* Finally get some more and try to fill. */
  314. if (od->token != ORANGEFS_ITERATE_END) {
  315. r = orangefs_dir_more(od, inode);
  316. if (r)
  317. return r;
  318. r = orangefs_dir_fill(od, ctx);
  319. }
  320. return r;
  321. }
  322. static int orangefs_dir_open(struct inode *inode, struct file *file)
  323. {
  324. struct orangefs_dir *od;
  325. file->private_data = kmalloc_obj(struct orangefs_dir);
  326. if (!file->private_data)
  327. return -ENOMEM;
  328. od = file->private_data;
  329. od->token = ORANGEFS_ITERATE_START;
  330. od->part = NULL;
  331. od->end = 1 << PART_SHIFT;
  332. od->error = 0;
  333. return 0;
  334. }
  335. static int orangefs_dir_release(struct inode *inode, struct file *file)
  336. {
  337. struct orangefs_dir *od = file->private_data;
  338. struct orangefs_dir_part *part = od->part;
  339. while (part) {
  340. struct orangefs_dir_part *next = part->next;
  341. vfree(part);
  342. part = next;
  343. }
  344. kfree(od);
  345. return 0;
  346. }
  347. const struct file_operations orangefs_dir_operations = {
  348. .llseek = orangefs_dir_llseek,
  349. .read = generic_read_dir,
  350. .iterate_shared = orangefs_dir_iterate,
  351. .open = orangefs_dir_open,
  352. .release = orangefs_dir_release,
  353. .setlease = generic_setlease,
  354. };