History

Merge tag 'ceph-for-4.17-rc1' of git://github.com/ceph/ceph-client

Pull ceph updates from Ilya Dryomov: "The big ticket items are: - support for rbd "fancy" striping (myself). The striping feature bit is now fully implemented, allowing mapping v2 images with non-default striping patterns. This completes support for --image-format 2. - CephFS quota support (Luis Henriques and Zheng Yan). This set is based on the new SnapRealm code in the upcoming v13.y.z ("Mimic") release. Quota handling will be rejected on older filesystems. - memory usage improvements in CephFS (Chengguang Xu). Directory specific bits have been split out of ceph_file_info and some effort went into improving cap reservation code to avoid OOM crashes. Also included a bunch of assorted fixes all over the place from Chengguang and others" * tag 'ceph-for-4.17-rc1' of git://github.com/ceph/ceph-client: (67 commits) ceph: quota: report root dir quota usage in statfs ceph: quota: add counter for snaprealms with quota ceph: quota: cache inode pointer in ceph_snap_realm ceph: fix root quota realm check ceph: don't check quota for snap inode ceph: quota: update MDS when max_bytes is approaching ceph: quota: support for ceph.quota.max_bytes ceph: quota: don't allow cross-quota renames ceph: quota: support for ceph.quota.max_files ceph: quota: add initial infrastructure to support cephfs quotas rbd: remove VLA usage rbd: fix spelling mistake: "reregisteration" -> "reregistration" ceph: rename function drop_leases() to a more descriptive name ceph: fix invalid point dereference for error case in mdsc destroy ceph: return proper bool type to caller instead of pointer ceph: optimize memory usage ceph: optimize mds session register libceph, ceph: add __init attribution to init funcitons ceph: filter out used flags when printing unused open flags ceph: don't wait on writeback when there is no more dirty pages ...

Linus Torvalds committed 8 years ago

Commit b284d4d2 parents a7726f6 9122eed35 files · +2558 −1920Browse files

Unified · Split

35 files
  1. Documentation/filesystems/ceph.txt +16 −0
  2. drivers/block/rbd.c +980 −1472
  3. fs/ceph/Makefile +1 −1
  4. fs/ceph/addr.c +32 −31
  5. fs/ceph/cache.c +2 −2
  6. fs/ceph/caps.c +97 −31
  7. fs/ceph/debugfs.c +4 −4
  8. fs/ceph/dir.c +112 −92
  9. fs/ceph/file.c +87 −30
  10. fs/ceph/inode.c +15 −11
  11. fs/ceph/ioctl.c +4 −9
  12. fs/ceph/locks.c +10 −10
  13. fs/ceph/mds_client.c +58 −29
  14. fs/ceph/mds_client.h +4 −0
  15. fs/ceph/quota.c +361 −0
  16. fs/ceph/snap.c +2 −0
  17. fs/ceph/super.c +39 −11
  18. fs/ceph/super.h +42 −0
  19. fs/ceph/xattr.c +44 −0
  20. include/linux/ceph/ceph_features.h +1 −0
  21. include/linux/ceph/ceph_fs.h +17 −0
  22. include/linux/ceph/libceph.h +1 −0
  23. include/linux/ceph/messenger.h +93 −8
  24. include/linux/ceph/osd_client.h +14 −5
  25. include/linux/ceph/osdmap.h +0 −6
  26. include/linux/ceph/striper.h +69 −0
  27. net/ceph/Makefile +1 −0
  28. net/ceph/ceph_common.c +7 −1
  29. net/ceph/crypto.c +4 −2
  30. net/ceph/debugfs.c +7 −10
  31. net/ceph/messenger.c +119 −69
  32. net/ceph/mon_client.c +1 −1
  33. net/ceph/osd_client.c +53 −14
  34. net/ceph/osdmap.c +0 −71
  35. net/ceph/striper.c +261 −0
Documentation/filesystems/ceph.txt+16−0
@@ -62,6 +62,18 @@ subdirectories, and a summation of all nested file sizes. This makes · 61 unmodified lines
6262 the identification of large disk space consumers relatively quick, as
6363 no 'du' or similar recursive scan of the file system is required.
6464
65+Finally, Ceph also allows quotas to be set on any directory in the system.
66+The quota can restrict the number of bytes or the number of files stored
67+beneath that point in the directory hierarchy. Quotas can be set using
68+extended attributes 'ceph.quota.max_files' and 'ceph.quota.max_bytes', eg:
69+
70+ setfattr -n ceph.quota.max_bytes -v 100000000 /some/dir
71+ getfattr -n ceph.quota.max_bytes /some/dir
72+
73+A limitation of the current quotas implementation is that it relies on the
74+cooperation of the client mounting the file system to stop writers when a
75+limit is reached. A modified or adversarial client cannot be prevented
76+from writing as much data as it needs.
6577
6678 Mount Syntax
6779 ============
@@ -137,6 +149,10 @@ Mount Options · 69 unmodified lines
137149 noasyncreaddir
138150 Do not use the dcache as above for readdir.
139151
152+ noquotadf
153+ Report overall filesystem usage in statfs instead of using the root
154+ directory quota.
155+
140156 More Information
141157 ================
142158
drivers/block/rbd.c+980−1472
@@ -32,6 +32,7 @@ · 31 unmodified lines
3232 #include <linux/ceph/osd_client.h>
3333 #include <linux/ceph/mon_client.h>
3434 #include <linux/ceph/cls_lock_client.h>
35+#include <linux/ceph/striper.h>
3536 #include <linux/ceph/decode.h>
3637 #include <linux/parser.h>
3738 #include <linux/bsearch.h>
@@ -200,95 +201,81 @@ struct rbd_client { · 162 unmodified lines
200201 };
201202
202203 struct rbd_img_request;
203−typedef void (*rbd_img_callback_t)(struct rbd_img_request *);
204−
205−#define BAD_WHICH U32_MAX /* Good which or bad which, which? */
206−
207−struct rbd_obj_request;
208−typedef void (*rbd_obj_callback_t)(struct rbd_obj_request *);
209204
210205 enum obj_request_type {
211− OBJ_REQUEST_NODATA, OBJ_REQUEST_BIO, OBJ_REQUEST_PAGES
206+ OBJ_REQUEST_NODATA = 1,
207+ OBJ_REQUEST_BIO, /* pointer into provided bio (list) */
208+ OBJ_REQUEST_BVECS, /* pointer into provided bio_vec array */
209+ OBJ_REQUEST_OWN_BVECS, /* private bio_vec array, doesn't own pages */
212210 };
213211
214212 enum obj_operation_type {
213+ OBJ_OP_READ = 1,
215214 OBJ_OP_WRITE,
216− OBJ_OP_READ,
217215 OBJ_OP_DISCARD,
218216 };
219217
220−enum obj_req_flags {
221− OBJ_REQ_DONE, /* completion flag: not done = 0, done = 1 */
222− OBJ_REQ_IMG_DATA, /* object usage: standalone = 0, image = 1 */
223− OBJ_REQ_KNOWN, /* EXISTS flag valid: no = 0, yes = 1 */
224− OBJ_REQ_EXISTS, /* target exists: no = 0, yes = 1 */
218+/*
219+ * Writes go through the following state machine to deal with
220+ * layering:
221+ *
222+ * need copyup
223+ * RBD_OBJ_WRITE_GUARD ---------------> RBD_OBJ_WRITE_COPYUP
224+ * | ^ |
225+ * v \------------------------------/
226+ * done
227+ * ^
228+ * |
229+ * RBD_OBJ_WRITE_FLAT
230+ *
231+ * Writes start in RBD_OBJ_WRITE_GUARD or _FLAT, depending on whether
232+ * there is a parent or not.
233+ */
234+enum rbd_obj_write_state {
235+ RBD_OBJ_WRITE_FLAT = 1,
236+ RBD_OBJ_WRITE_GUARD,
237+ RBD_OBJ_WRITE_COPYUP,
225238 };
226239
227240 struct rbd_obj_request {
228− u64 object_no;
229− u64 offset; /* object start byte */
230− u64 length; /* bytes from offset */
231− unsigned long flags;
232−
233− /*
234− * An object request associated with an image will have its
235− * img_data flag set; a standalone object request will not.
236− *
237− * A standalone object request will have which == BAD_WHICH
238− * and a null obj_request pointer.
239− *
240− * An object request initiated in support of a layered image
241− * object (to check for its existence before a write) will
242− * have which == BAD_WHICH and a non-null obj_request pointer.
243− *
244− * Finally, an object request for rbd image data will have
245− * which != BAD_WHICH, and will have a non-null img_request
246− * pointer. The value of which will be in the range
247− * 0..(img_request->obj_request_count-1).
248− */
241+ struct ceph_object_extent ex;
249242 union {
250− struct rbd_obj_request *obj_request; /* STAT op */
251− struct {
252− struct rbd_img_request *img_request;
253− u64 img_offset;
254− /* links for img_request->obj_requests list */
255− struct list_head links;
256− };
243+ bool tried_parent; /* for reads */
244+ enum rbd_obj_write_state write_state; /* for writes */
257245 };
258− u32 which; /* posn image request list */
259246
260− enum obj_request_type type;
247+ struct rbd_img_request *img_request;
248+ struct ceph_file_extent *img_extents;
249+ u32 num_img_extents;
250+
261251 union {
262− struct bio *bio_list;
252+ struct ceph_bio_iter bio_pos;
263253 struct {
264− struct page **pages;
265− u32 page_count;
254+ struct ceph_bvec_iter bvec_pos;
255+ u32 bvec_count;
256+ u32 bvec_idx;
266257 };
267258 };
268− struct page **copyup_pages;
269− u32 copyup_page_count;
259+ struct bio_vec *copyup_bvecs;
260+ u32 copyup_bvec_count;
270261
271262 struct ceph_osd_request *osd_req;
272263
273264 u64 xferred; /* bytes transferred */
274265 int result;
275266
276− rbd_obj_callback_t callback;
277−
278267 struct kref kref;
279268 };
280269
281270 enum img_req_flags {
282− IMG_REQ_WRITE, /* I/O direction: read = 0, write = 1 */
283271 IMG_REQ_CHILD, /* initiator: block = 0, child image = 1 */
284272 IMG_REQ_LAYERED, /* ENOENT handling: normal = 0, layered = 1 */
285− IMG_REQ_DISCARD, /* discard: normal = 0, discard request = 1 */
286273 };
287274
288275 struct rbd_img_request {
289276 struct rbd_device *rbd_dev;
290− u64 offset; /* starting image byte offset */
291− u64 length; /* byte count from offset */
277+ enum obj_operation_type op_type;
278+ enum obj_request_type data_type;
292279 unsigned long flags;
293280 union {
294281 u64 snap_id; /* for reads */
@@ -298,26 +285,21 @@ struct rbd_img_request { · 3 unmodified lines
298285 struct request *rq; /* block request */
299286 struct rbd_obj_request *obj_request; /* obj req initiator */
300287 };
301− struct page **copyup_pages;
302− u32 copyup_page_count;
303− spinlock_t completion_lock;/* protects next_completion */
304− u32 next_completion;
305− rbd_img_callback_t callback;
288+ spinlock_t completion_lock;
306289 u64 xferred;/* aggregate bytes transferred */
307290 int result; /* first nonzero obj_request result */
308291
292+ struct list_head object_extents; /* obj_req.ex structs */
309293 u32 obj_request_count;
310− struct list_head obj_requests; /* rbd_obj_request structs */
294+ u32 pending_count;
311295
312296 struct kref kref;
313297 };
314298
315299 #define for_each_obj_request(ireq, oreq) \
316− list_for_each_entry(oreq, &(ireq)->obj_requests, links)
317−#define for_each_obj_request_from(ireq, oreq) \
318− list_for_each_entry_from(oreq, &(ireq)->obj_requests, links)
300+ list_for_each_entry(oreq, &(ireq)->object_extents, ex.oe_item)
319301 #define for_each_obj_request_safe(ireq, oreq, n) \
320− list_for_each_entry_safe_reverse(oreq, n, &(ireq)->obj_requests, links)
302+ list_for_each_entry_safe(oreq, n, &(ireq)->object_extents, ex.oe_item)
321303
322304 enum rbd_watch_state {
323305 RBD_WATCH_STATE_UNREGISTERED,
@@ -433,8 +415,6 @@ static DEFINE_SPINLOCK(rbd_client_list_lock); · 109 unmodified lines
433415 static struct kmem_cache *rbd_img_request_cache;
434416 static struct kmem_cache *rbd_obj_request_cache;
435417
436−static struct bio_set *rbd_bio_clone;
437−
438418 static int rbd_major;
439419 static DEFINE_IDA(rbd_dev_id_ida);
440420
@@ -447,8 +427,6 @@ static bool single_major = true; · 6 unmodified lines
447427 module_param(single_major, bool, S_IRUGO);
448428 MODULE_PARM_DESC(single_major, "Use a single major number for all rbd devices (default: true)");
449429
450−static int rbd_img_request_submit(struct rbd_img_request *img_request);
451−
452430 static ssize_t rbd_add(struct bus_type *bus, const char *buf,
453431 size_t count);
454432 static ssize_t rbd_remove(struct bus_type *bus, const char *buf,
@@ -458,7 +436,6 @@ static ssize_t rbd_add_single_major(struct bus_type *bus, const char *buf, · 3 unmodified lines
458436 static ssize_t rbd_remove_single_major(struct bus_type *bus, const char *buf,
459437 size_t count);
460438 static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth);
461−static void rbd_spec_put(struct rbd_spec *spec);
462439
463440 static int rbd_dev_id_to_minor(int dev_id)
464441 {
@@ -577,9 +554,6 @@ void rbd_warn(struct rbd_device *rbd_dev, const char *fmt, ...) · 112 unmodified lines
577554 # define rbd_assert(expr) ((void) 0)
578555 #endif /* !RBD_DEBUG */
579556
580−static void rbd_osd_copyup_callback(struct rbd_obj_request *obj_request);
581−static int rbd_img_obj_request_submit(struct rbd_obj_request *obj_request);
582−static void rbd_img_parent_read(struct rbd_obj_request *obj_request);
583557 static void rbd_dev_remove_parent(struct rbd_device *rbd_dev);
584558
585559 static int rbd_dev_refresh(struct rbd_device *rbd_dev);
@@ -856,26 +830,6 @@ static char* obj_op_name(enum obj_operation_type op_type) · 270 unmodified lines
856830 }
857831 }
858832
859−/*
860− * Get a ceph client with specific addr and configuration, if one does
861− * not exist create it. Either way, ceph_opts is consumed by this
862− * function.
863− */
864−static struct rbd_client *rbd_get_client(struct ceph_options *ceph_opts)
865−{
866− struct rbd_client *rbdc;
867−
868− mutex_lock_nested(&client_mutex, SINGLE_DEPTH_NESTING);
869− rbdc = rbd_client_find(ceph_opts);
870− if (rbdc) /* using an existing client */
871− ceph_destroy_options(ceph_opts);
872− else
873− rbdc = rbd_client_create(ceph_opts);
874− mutex_unlock(&client_mutex);
875−
876− return rbdc;
877−}
878−
879833 /*
880834 * Destroy ceph client
881835 *
@@ -904,6 +858,56 @@ static void rbd_put_client(struct rbd_client *rbdc) · 22 unmodified lines
904858 kref_put(&rbdc->kref, rbd_client_release);
905859 }
906860
861+static int wait_for_latest_osdmap(struct ceph_client *client)
862+{
863+ u64 newest_epoch;
864+ int ret;
865+
866+ ret = ceph_monc_get_version(&client->monc, "osdmap", &newest_epoch);
867+ if (ret)
868+ return ret;
869+
870+ if (client->osdc.osdmap->epoch >= newest_epoch)
871+ return 0;
872+
873+ ceph_osdc_maybe_request_map(&client->osdc);
874+ return ceph_monc_wait_osdmap(&client->monc, newest_epoch,
875+ client->options->mount_timeout);
876+}
877+
878+/*
879+ * Get a ceph client with specific addr and configuration, if one does
880+ * not exist create it. Either way, ceph_opts is consumed by this
881+ * function.
882+ */
883+static struct rbd_client *rbd_get_client(struct ceph_options *ceph_opts)
884+{
885+ struct rbd_client *rbdc;
886+ int ret;
887+
888+ mutex_lock_nested(&client_mutex, SINGLE_DEPTH_NESTING);
889+ rbdc = rbd_client_find(ceph_opts);
890+ if (rbdc) {
891+ ceph_destroy_options(ceph_opts);
892+
893+ /*
894+ * Using an existing client. Make sure ->pg_pools is up to
895+ * date before we look up the pool id in do_rbd_add().
896+ */
897+ ret = wait_for_latest_osdmap(rbdc->client);
898+ if (ret) {
899+ rbd_warn(NULL, "failed to get latest osdmap: %d", ret);
900+ rbd_put_client(rbdc);
901+ rbdc = ERR_PTR(ret);
902+ }
903+ } else {
904+ rbdc = rbd_client_create(ceph_opts);
905+ }
906+ mutex_unlock(&client_mutex);
907+
908+ return rbdc;
909+}
910+
907911 static bool rbd_image_format_valid(u32 image_format)
908912 {
909913 return image_format == 1 || image_format == 2;
@@ -1223,272 +1227,59 @@ static void rbd_dev_mapping_clear(struct rbd_device *rbd_dev) · 313 unmodified lines
12231227 rbd_dev->mapping.features = 0;
12241228 }
12251229
1226−static u64 rbd_segment_offset(struct rbd_device *rbd_dev, u64 offset)
1227−{
1228− u64 segment_size = rbd_obj_bytes(&rbd_dev->header);
1229−
1230− return offset & (segment_size - 1);
1231−}
1232−
1233−static u64 rbd_segment_length(struct rbd_device *rbd_dev,
1234− u64 offset, u64 length)
1235−{
1236− u64 segment_size = rbd_obj_bytes(&rbd_dev->header);
1237−
1238− offset &= segment_size - 1;
1239−
1240− rbd_assert(length <= U64_MAX - offset);
1241− if (offset + length > segment_size)
1242− length = segment_size - offset;
1243−
1244− return length;
1245−}
1246−
1247−/*
1248− * bio helpers
1249− */
1250−
1251−static void bio_chain_put(struct bio *chain)
1252−{
1253− struct bio *tmp;
1254−
1255− while (chain) {
1256− tmp = chain;
1257− chain = chain->bi_next;
1258− bio_put(tmp);
1259− }
1260−}
1261−
1262−/*
1263− * zeros a bio chain, starting at specific offset
1264− */
1265−static void zero_bio_chain(struct bio *chain, int start_ofs)
1230+static void zero_bvec(struct bio_vec *bv)
12661231 {
1267− struct bio_vec bv;
1268− struct bvec_iter iter;
1269− unsigned long flags;
12701232 void *buf;
1271− int pos = 0;
1272−
1273− while (chain) {
1274− bio_for_each_segment(bv, chain, iter) {
1275− if (pos + bv.bv_len > start_ofs) {
1276− int remainder = max(start_ofs - pos, 0);
1277− buf = bvec_kmap_irq(&bv, &flags);
1278− memset(buf + remainder, 0,
1279− bv.bv_len - remainder);
1280− flush_dcache_page(bv.bv_page);
1281− bvec_kunmap_irq(buf, &flags);
1282− }
1283− pos += bv.bv_len;
1284− }
1233+ unsigned long flags;
12851234
1286− chain = chain->bi_next;
1287− }
1235+ buf = bvec_kmap_irq(bv, &flags);
1236+ memset(buf, 0, bv->bv_len);
1237+ flush_dcache_page(bv->bv_page);
1238+ bvec_kunmap_irq(buf, &flags);
12881239 }
12891240
1290−/*
1291− * similar to zero_bio_chain(), zeros data defined by a page array,
1292− * starting at the given byte offset from the start of the array and
1293− * continuing up to the given end offset. The pages array is
1294− * assumed to be big enough to hold all bytes up to the end.
1295− */
1296−static void zero_pages(struct page **pages, u64 offset, u64 end)
1241+static void zero_bios(struct ceph_bio_iter *bio_pos, u32 off, u32 bytes)
12971242 {
1298− struct page **page = &pages[offset >> PAGE_SHIFT];
1299−
1300− rbd_assert(end > offset);
1301− rbd_assert(end - offset <= (u64)SIZE_MAX);
1302− while (offset < end) {
1303− size_t page_offset;
1304− size_t length;
1305− unsigned long flags;
1306− void *kaddr;
1307−
1308− page_offset = offset & ~PAGE_MASK;
1309− length = min_t(size_t, PAGE_SIZE - page_offset, end - offset);
1310− local_irq_save(flags);
1311− kaddr = kmap_atomic(*page);
1312− memset(kaddr + page_offset, 0, length);
1313− flush_dcache_page(*page);
1314− kunmap_atomic(kaddr);
1315− local_irq_restore(flags);
1243+ struct ceph_bio_iter it = *bio_pos;
13161244
1317− offset += length;
1318− page++;
1319− }
1245+ ceph_bio_iter_advance(&it, off);
1246+ ceph_bio_iter_advance_step(&it, bytes, ({
1247+ zero_bvec(&bv);
1248+ }));
13201249 }
13211250
1322−/*
1323− * Clone a portion of a bio, starting at the given byte offset
1324− * and continuing for the number of bytes indicated.
1325− */
1326−static struct bio *bio_clone_range(struct bio *bio_src,
1327− unsigned int offset,
1328− unsigned int len,
1329− gfp_t gfpmask)
1251+static void zero_bvecs(struct ceph_bvec_iter *bvec_pos, u32 off, u32 bytes)
13301252 {
1331− struct bio *bio;
1332−
1333− bio = bio_clone_fast(bio_src, gfpmask, rbd_bio_clone);
1334− if (!bio)
1335− return NULL; /* ENOMEM */
1253+ struct ceph_bvec_iter it = *bvec_pos;
13361254
1337− bio_advance(bio, offset);
1338− bio->bi_iter.bi_size = len;
1339−
1340− return bio;
1255+ ceph_bvec_iter_advance(&it, off);
1256+ ceph_bvec_iter_advance_step(&it, bytes, ({
1257+ zero_bvec(&bv);
1258+ }));
13411259 }
13421260
13431261 /*
1344− * Clone a portion of a bio chain, starting at the given byte offset
1345− * into the first bio in the source chain and continuing for the
1346− * number of bytes indicated. The result is another bio chain of
1347− * exactly the given length, or a null pointer on error.
1348− *
1349− * The bio_src and offset parameters are both in-out. On entry they
1350− * refer to the first source bio and the offset into that bio where
1351− * the start of data to be cloned is located.
1262+ * Zero a range in @obj_req data buffer defined by a bio (list) or
1263+ * (private) bio_vec array.
13521264 *
1353− * On return, bio_src is updated to refer to the bio in the source
1354− * chain that contains first un-cloned byte, and *offset will
1355− * contain the offset of that byte within that bio.
1356− */
1357−static struct bio *bio_chain_clone_range(struct bio **bio_src,
1358− unsigned int *offset,
1359− unsigned int len,
1360− gfp_t gfpmask)
1361−{
1362− struct bio *bi = *bio_src;
1363− unsigned int off = *offset;
1364− struct bio *chain = NULL;
1365− struct bio **end;
1366−
1367− /* Build up a chain of clone bios up to the limit */
1368−
1369− if (!bi || off >= bi->bi_iter.bi_size || !len)
1370− return NULL; /* Nothing to clone */
1371−
1372− end = &chain;
1373− while (len) {
1374− unsigned int bi_size;
1375− struct bio *bio;
1376−
1377− if (!bi) {
1378− rbd_warn(NULL, "bio_chain exhausted with %u left", len);
1379− goto out_err; /* EINVAL; ran out of bio's */
1380− }
1381− bi_size = min_t(unsigned int, bi->bi_iter.bi_size - off, len);
1382− bio = bio_clone_range(bi, off, bi_size, gfpmask);
1383− if (!bio)
1384− goto out_err; /* ENOMEM */
1385−
1386− *end = bio;
1387− end = &bio->bi_next;
1388−
1389− off += bi_size;
1390− if (off == bi->bi_iter.bi_size) {
1391− bi = bi->bi_next;
1392− off = 0;
1393− }
1394− len -= bi_size;
1395− }
1396− *bio_src = bi;
1397− *offset = off;
1398−
1399− return chain;
1400−out_err:
1401− bio_chain_put(chain);
1402−
1403− return NULL;
1404−}
1405−
1406−/*
1407− * The default/initial value for all object request flags is 0. For
1408− * each flag, once its value is set to 1 it is never reset to 0
1409− * again.
1265+ * @off is relative to the start of the data buffer.
14101266 */
1411−static void obj_request_img_data_set(struct rbd_obj_request *obj_request)
1412−{
1413− if (test_and_set_bit(OBJ_REQ_IMG_DATA, &obj_request->flags)) {
1414− struct rbd_device *rbd_dev;
1415−
1416− rbd_dev = obj_request->img_request->rbd_dev;
1417− rbd_warn(rbd_dev, "obj_request %p already marked img_data",
1418− obj_request);
1419− }
1420−}
1421−
1422−static bool obj_request_img_data_test(struct rbd_obj_request *obj_request)
1267+static void rbd_obj_zero_range(struct rbd_obj_request *obj_req, u32 off,
1268+ u32 bytes)
14231269 {
1424− smp_mb();
1425− return test_bit(OBJ_REQ_IMG_DATA, &obj_request->flags) != 0;
1426−}
1427−
1428−static void obj_request_done_set(struct rbd_obj_request *obj_request)
1429−{
1430− if (test_and_set_bit(OBJ_REQ_DONE, &obj_request->flags)) {
1431− struct rbd_device *rbd_dev = NULL;
1432−
1433− if (obj_request_img_data_test(obj_request))
1434− rbd_dev = obj_request->img_request->rbd_dev;
1435− rbd_warn(rbd_dev, "obj_request %p already marked done",
1436− obj_request);
1270+ switch (obj_req->img_request->data_type) {
1271+ case OBJ_REQUEST_BIO:
1272+ zero_bios(&obj_req->bio_pos, off, bytes);
1273+ break;
1274+ case OBJ_REQUEST_BVECS:
1275+ case OBJ_REQUEST_OWN_BVECS:
1276+ zero_bvecs(&obj_req->bvec_pos, off, bytes);
1277+ break;
1278+ default:
1279+ rbd_assert(0);
14371280 }
14381281 }
14391282
1440−static bool obj_request_done_test(struct rbd_obj_request *obj_request)
1441−{
1442− smp_mb();
1443− return test_bit(OBJ_REQ_DONE, &obj_request->flags) != 0;
1444−}
1445−
1446−/*
1447− * This sets the KNOWN flag after (possibly) setting the EXISTS
1448− * flag. The latter is set based on the "exists" value provided.
1449− *
1450− * Note that for our purposes once an object exists it never goes
1451− * away again. It's possible that the response from two existence
1452− * checks are separated by the creation of the target object, and
1453− * the first ("doesn't exist") response arrives *after* the second
1454− * ("does exist"). In that case we ignore the second one.
1455− */
1456−static void obj_request_existence_set(struct rbd_obj_request *obj_request,
1457− bool exists)
1458−{
1459− if (exists)
1460− set_bit(OBJ_REQ_EXISTS, &obj_request->flags);
1461− set_bit(OBJ_REQ_KNOWN, &obj_request->flags);
1462− smp_mb();
1463−}
1464−
1465−static bool obj_request_known_test(struct rbd_obj_request *obj_request)
1466−{
1467− smp_mb();
1468− return test_bit(OBJ_REQ_KNOWN, &obj_request->flags) != 0;
1469−}
1470−
1471−static bool obj_request_exists_test(struct rbd_obj_request *obj_request)
1472−{
1473− smp_mb();
1474− return test_bit(OBJ_REQ_EXISTS, &obj_request->flags) != 0;
1475−}
1476−
1477−static bool obj_request_overlaps_parent(struct rbd_obj_request *obj_request)
1478−{
1479− struct rbd_device *rbd_dev = obj_request->img_request->rbd_dev;
1480−
1481− return obj_request->img_offset <
1482− round_up(rbd_dev->parent_overlap, rbd_obj_bytes(&rbd_dev->header));
1483−}
1484−
1485−static void rbd_obj_request_get(struct rbd_obj_request *obj_request)
1486−{
1487− dout("%s: obj %p (was %d)\n", __func__, obj_request,
1488− kref_read(&obj_request->kref));
1489− kref_get(&obj_request->kref);
1490−}
1491−
14921283 static void rbd_obj_request_destroy(struct kref *kref);
14931284 static void rbd_obj_request_put(struct rbd_obj_request *obj_request)
14941285 {
@@ -1505,18 +1296,13 @@ static void rbd_img_request_get(struct rbd_img_request *img_request) · 10 unmodified lines
15051296 kref_get(&img_request->kref);
15061297 }
15071298
1508−static bool img_request_child_test(struct rbd_img_request *img_request);
1509−static void rbd_parent_request_destroy(struct kref *kref);
15101299 static void rbd_img_request_destroy(struct kref *kref);
15111300 static void rbd_img_request_put(struct rbd_img_request *img_request)
15121301 {
15131302 rbd_assert(img_request != NULL);
15141303 dout("%s: img %p (was %d)\n", __func__, img_request,
15151304 kref_read(&img_request->kref));
1516− if (img_request_child_test(img_request))
1517− kref_put(&img_request->kref, rbd_parent_request_destroy);
1518− else
1519− kref_put(&img_request->kref, rbd_img_request_destroy);
1305+ kref_put(&img_request->kref, rbd_img_request_destroy);
15201306 }
15211307
15221308 static inline void rbd_img_obj_request_add(struct rbd_img_request *img_request,
@@ -1526,139 +1312,37 @@ static inline void rbd_img_obj_request_add(struct rbd_img_request *img_request, · 3 unmodified lines
15261312
15271313 /* Image request now owns object's original reference */
15281314 obj_request->img_request = img_request;
1529− obj_request->which = img_request->obj_request_count;
1530− rbd_assert(!obj_request_img_data_test(obj_request));
1531− obj_request_img_data_set(obj_request);
1532− rbd_assert(obj_request->which != BAD_WHICH);
15331315 img_request->obj_request_count++;
1534− list_add_tail(&obj_request->links, &img_request->obj_requests);
1535− dout("%s: img %p obj %p w=%u\n", __func__, img_request, obj_request,
1536− obj_request->which);
1316+ img_request->pending_count++;
1317+ dout("%s: img %p obj %p\n", __func__, img_request, obj_request);
15371318 }
15381319
15391320 static inline void rbd_img_obj_request_del(struct rbd_img_request *img_request,
15401321 struct rbd_obj_request *obj_request)
15411322 {
1542− rbd_assert(obj_request->which != BAD_WHICH);
1543−
1544− dout("%s: img %p obj %p w=%u\n", __func__, img_request, obj_request,
1545− obj_request->which);
1546− list_del(&obj_request->links);
1323+ dout("%s: img %p obj %p\n", __func__, img_request, obj_request);
1324+ list_del(&obj_request->ex.oe_item);
15471325 rbd_assert(img_request->obj_request_count > 0);
15481326 img_request->obj_request_count--;
1549− rbd_assert(obj_request->which == img_request->obj_request_count);
1550− obj_request->which = BAD_WHICH;
1551− rbd_assert(obj_request_img_data_test(obj_request));
15521327 rbd_assert(obj_request->img_request == img_request);
1553− obj_request->img_request = NULL;
1554− obj_request->callback = NULL;
15551328 rbd_obj_request_put(obj_request);
15561329 }
15571330
1558−static bool obj_request_type_valid(enum obj_request_type type)
1559−{
1560− switch (type) {
1561− case OBJ_REQUEST_NODATA:
1562− case OBJ_REQUEST_BIO:
1563− case OBJ_REQUEST_PAGES:
1564− return true;
1565− default:
1566− return false;
1567− }
1568−}
1569−
1570−static void rbd_img_obj_callback(struct rbd_obj_request *obj_request);
1571−
15721331 static void rbd_obj_request_submit(struct rbd_obj_request *obj_request)
15731332 {
15741333 struct ceph_osd_request *osd_req = obj_request->osd_req;
15751334
15761335 dout("%s %p object_no %016llx %llu~%llu osd_req %p\n", __func__,
1577− obj_request, obj_request->object_no, obj_request->offset,
1578− obj_request->length, osd_req);
1579− if (obj_request_img_data_test(obj_request)) {
1580− WARN_ON(obj_request->callback != rbd_img_obj_callback);
1581− rbd_img_request_get(obj_request->img_request);
1582− }
1336+ obj_request, obj_request->ex.oe_objno, obj_request->ex.oe_off,
1337+ obj_request->ex.oe_len, osd_req);
15831338 ceph_osdc_start_request(osd_req->r_osdc, osd_req, false);
15841339 }
15851340
1586−static void rbd_img_request_complete(struct rbd_img_request *img_request)
1587−{
1588−
1589− dout("%s: img %p\n", __func__, img_request);
1590−
1591− /*
1592− * If no error occurred, compute the aggregate transfer
1593− * count for the image request. We could instead use
1594− * atomic64_cmpxchg() to update it as each object request
1595− * completes; not clear which way is better off hand.
1596− */
1597− if (!img_request->result) {
1598− struct rbd_obj_request *obj_request;
1599− u64 xferred = 0;
1600−
1601− for_each_obj_request(img_request, obj_request)
1602− xferred += obj_request->xferred;
1603− img_request->xferred = xferred;
1604− }
1605−
1606− if (img_request->callback)
1607− img_request->callback(img_request);
1608− else
1609− rbd_img_request_put(img_request);
1610−}
1611−
16121341 /*
16131342 * The default/initial value for all image request flags is 0. Each
16141343 * is conditionally set to 1 at image request initialization time
16151344 * and currently never change thereafter.
16161345 */
1617−static void img_request_write_set(struct rbd_img_request *img_request)
1618−{
1619− set_bit(IMG_REQ_WRITE, &img_request->flags);
1620− smp_mb();
1621−}
1622−
1623−static bool img_request_write_test(struct rbd_img_request *img_request)
1624−{
1625− smp_mb();
1626− return test_bit(IMG_REQ_WRITE, &img_request->flags) != 0;
1627−}
1628−
1629−/*
1630− * Set the discard flag when the img_request is an discard request
1631− */
1632−static void img_request_discard_set(struct rbd_img_request *img_request)
1633−{
1634− set_bit(IMG_REQ_DISCARD, &img_request->flags);
1635− smp_mb();
1636−}
1637−
1638−static bool img_request_discard_test(struct rbd_img_request *img_request)
1639−{
1640− smp_mb();
1641− return test_bit(IMG_REQ_DISCARD, &img_request->flags) != 0;
1642−}
1643−
1644−static void img_request_child_set(struct rbd_img_request *img_request)
1645−{
1646− set_bit(IMG_REQ_CHILD, &img_request->flags);
1647− smp_mb();
1648−}
1649−
1650−static void img_request_child_clear(struct rbd_img_request *img_request)
1651−{
1652− clear_bit(IMG_REQ_CHILD, &img_request->flags);
1653− smp_mb();
1654−}
1655−
1656−static bool img_request_child_test(struct rbd_img_request *img_request)
1657−{
1658− smp_mb();
1659− return test_bit(IMG_REQ_CHILD, &img_request->flags) != 0;
1660−}
1661−
16621346 static void img_request_layered_set(struct rbd_img_request *img_request)
16631347 {
16641348 set_bit(IMG_REQ_LAYERED, &img_request->flags);
@@ -1677,209 +1361,70 @@ static bool img_request_layered_test(struct rbd_img_request *img_request) · 12 unmodified lines
16771361 return test_bit(IMG_REQ_LAYERED, &img_request->flags) != 0;
16781362 }
16791363
1680−static enum obj_operation_type
1681−rbd_img_request_op_type(struct rbd_img_request *img_request)
1682−{
1683− if (img_request_write_test(img_request))
1684− return OBJ_OP_WRITE;
1685− else if (img_request_discard_test(img_request))
1686− return OBJ_OP_DISCARD;
1687− else
1688− return OBJ_OP_READ;
1689−}
1690−
1691−static void
1692−rbd_img_obj_request_read_callback(struct rbd_obj_request *obj_request)
1364+static bool rbd_obj_is_entire(struct rbd_obj_request *obj_req)
16931365 {
1694− u64 xferred = obj_request->xferred;
1695− u64 length = obj_request->length;
1366+ struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev;
16961367
1697− dout("%s: obj %p img %p result %d %llu/%llu\n", __func__,
1698− obj_request, obj_request->img_request, obj_request->result,
1699− xferred, length);
1700− /*
1701− * ENOENT means a hole in the image. We zero-fill the entire
1702− * length of the request. A short read also implies zero-fill
1703− * to the end of the request. An error requires the whole
1704− * length of the request to be reported finished with an error
1705− * to the block layer. In each case we update the xferred
1706− * count to indicate the whole request was satisfied.
1707− */
1708− rbd_assert(obj_request->type != OBJ_REQUEST_NODATA);
1709− if (obj_request->result == -ENOENT) {
1710− if (obj_request->type == OBJ_REQUEST_BIO)
1711− zero_bio_chain(obj_request->bio_list, 0);
1712− else
1713− zero_pages(obj_request->pages, 0, length);
1714− obj_request->result = 0;
1715− } else if (xferred < length && !obj_request->result) {
1716− if (obj_request->type == OBJ_REQUEST_BIO)
1717− zero_bio_chain(obj_request->bio_list, xferred);
1718− else
1719− zero_pages(obj_request->pages, xferred, length);
1720− }
1721− obj_request->xferred = length;
1722− obj_request_done_set(obj_request);
1368+ return !obj_req->ex.oe_off &&
1369+ obj_req->ex.oe_len == rbd_dev->layout.object_size;
17231370 }
17241371
1725−static void rbd_obj_request_complete(struct rbd_obj_request *obj_request)
1372+static bool rbd_obj_is_tail(struct rbd_obj_request *obj_req)
17261373 {
1727− dout("%s: obj %p cb %p\n", __func__, obj_request,
1728− obj_request->callback);
1729− obj_request->callback(obj_request);
1730−}
1374+ struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev;
17311375
1732−static void rbd_obj_request_error(struct rbd_obj_request *obj_request, int err)
1733−{
1734− obj_request->result = err;
1735− obj_request->xferred = 0;
1736− /*
1737− * kludge - mirror rbd_obj_request_submit() to match a put in
1738− * rbd_img_obj_callback()
1739− */
1740− if (obj_request_img_data_test(obj_request)) {
1741− WARN_ON(obj_request->callback != rbd_img_obj_callback);
1742− rbd_img_request_get(obj_request->img_request);
1743− }
1744− obj_request_done_set(obj_request);
1745− rbd_obj_request_complete(obj_request);
1376+ return obj_req->ex.oe_off + obj_req->ex.oe_len ==
1377+ rbd_dev->layout.object_size;
17461378 }
17471379
1748−static void rbd_osd_read_callback(struct rbd_obj_request *obj_request)
1380+static u64 rbd_obj_img_extents_bytes(struct rbd_obj_request *obj_req)
17491381 {
1750− struct rbd_img_request *img_request = NULL;
1751− struct rbd_device *rbd_dev = NULL;
1752− bool layered = false;
1753−
1754− if (obj_request_img_data_test(obj_request)) {
1755− img_request = obj_request->img_request;
1756− layered = img_request && img_request_layered_test(img_request);
1757− rbd_dev = img_request->rbd_dev;
1758− }
1759−
1760− dout("%s: obj %p img %p result %d %llu/%llu\n", __func__,
1761− obj_request, img_request, obj_request->result,
1762− obj_request->xferred, obj_request->length);
1763− if (layered && obj_request->result == -ENOENT &&
1764− obj_request->img_offset < rbd_dev->parent_overlap)
1765− rbd_img_parent_read(obj_request);
1766− else if (img_request)
1767− rbd_img_obj_request_read_callback(obj_request);
1768− else
1769− obj_request_done_set(obj_request);
1382+ return ceph_file_extents_bytes(obj_req->img_extents,
1383+ obj_req->num_img_extents);
17701384 }
17711385
1772−static void rbd_osd_write_callback(struct rbd_obj_request *obj_request)
1386+static bool rbd_img_is_write(struct rbd_img_request *img_req)
17731387 {
1774− dout("%s: obj %p result %d %llu\n", __func__, obj_request,
1775− obj_request->result, obj_request->length);
1776− /*
1777− * There is no such thing as a successful short write. Set
1778− * it to our originally-requested length.
1779− */
1780− obj_request->xferred = obj_request->length;
1781− obj_request_done_set(obj_request);
1782−}
1783−
1784−static void rbd_osd_discard_callback(struct rbd_obj_request *obj_request)
1785−{
1786− dout("%s: obj %p result %d %llu\n", __func__, obj_request,
1787− obj_request->result, obj_request->length);
1788− /*
1789− * There is no such thing as a successful short discard. Set
1790− * it to our originally-requested length.
1791− */
1792− obj_request->xferred = obj_request->length;
1793− /* discarding a non-existent object is not a problem */
1794− if (obj_request->result == -ENOENT)
1795− obj_request->result = 0;
1796− obj_request_done_set(obj_request);
1388+ switch (img_req->op_type) {
1389+ case OBJ_OP_READ:
1390+ return false;
1391+ case OBJ_OP_WRITE:
1392+ case OBJ_OP_DISCARD:
1393+ return true;
1394+ default:
1395+ rbd_assert(0);
1396+ }
17971397 }
17981398
1799−/*
1800− * For a simple stat call there's nothing to do. We'll do more if
1801− * this is part of a write sequence for a layered image.
1802− */
1803−static void rbd_osd_stat_callback(struct rbd_obj_request *obj_request)
1804−{
1805− dout("%s: obj %p\n", __func__, obj_request);
1806− obj_request_done_set(obj_request);
1807−}
1808−
1809−static void rbd_osd_call_callback(struct rbd_obj_request *obj_request)
1810−{
1811− dout("%s: obj %p\n", __func__, obj_request);
1812−
1813− if (obj_request_img_data_test(obj_request))
1814− rbd_osd_copyup_callback(obj_request);
1815− else
1816− obj_request_done_set(obj_request);
1817−}
1399+static void rbd_obj_handle_request(struct rbd_obj_request *obj_req);
18181400
18191401 static void rbd_osd_req_callback(struct ceph_osd_request *osd_req)
18201402 {
1821− struct rbd_obj_request *obj_request = osd_req->r_priv;
1822− u16 opcode;
1403+ struct rbd_obj_request *obj_req = osd_req->r_priv;
18231404
1824− dout("%s: osd_req %p\n", __func__, osd_req);
1825− rbd_assert(osd_req == obj_request->osd_req);
1826− if (obj_request_img_data_test(obj_request)) {
1827− rbd_assert(obj_request->img_request);
1828− rbd_assert(obj_request->which != BAD_WHICH);
1829− } else {
1830− rbd_assert(obj_request->which == BAD_WHICH);
1831− }
1405+ dout("%s osd_req %p result %d for obj_req %p\n", __func__, osd_req,
1406+ osd_req->r_result, obj_req);
1407+ rbd_assert(osd_req == obj_req->osd_req);
18321408
1833− if (osd_req->r_result < 0)
1834− obj_request->result = osd_req->r_result;
1835−
1836− /*
1837− * We support a 64-bit length, but ultimately it has to be
1838− * passed to the block layer, which just supports a 32-bit
1839− * length field.
1840− */
1841− obj_request->xferred = osd_req->r_ops[0].outdata_len;
1842− rbd_assert(obj_request->xferred < (u64)UINT_MAX);
1843−
1844− opcode = osd_req->r_ops[0].op;
1845− switch (opcode) {
1846− case CEPH_OSD_OP_READ:
1847− rbd_osd_read_callback(obj_request);
1848− break;
1849− case CEPH_OSD_OP_SETALLOCHINT:
1850− rbd_assert(osd_req->r_ops[1].op == CEPH_OSD_OP_WRITE ||
1851− osd_req->r_ops[1].op == CEPH_OSD_OP_WRITEFULL);
1852− /* fall through */
1853− case CEPH_OSD_OP_WRITE:
1854− case CEPH_OSD_OP_WRITEFULL:
1855− rbd_osd_write_callback(obj_request);
1856− break;
1857− case CEPH_OSD_OP_STAT:
1858− rbd_osd_stat_callback(obj_request);
1859− break;
1860− case CEPH_OSD_OP_DELETE:
1861− case CEPH_OSD_OP_TRUNCATE:
1862− case CEPH_OSD_OP_ZERO:
1863− rbd_osd_discard_callback(obj_request);
1864− break;
1865− case CEPH_OSD_OP_CALL:
1866− rbd_osd_call_callback(obj_request);
1867− break;
1868− default:
1869− rbd_warn(NULL, "unexpected OSD op: object_no %016llx opcode %d",
1870− obj_request->object_no, opcode);
1871− break;
1872− }
1409+ obj_req->result = osd_req->r_result < 0 ? osd_req->r_result : 0;
1410+ if (!obj_req->result && !rbd_img_is_write(obj_req->img_request))
1411+ obj_req->xferred = osd_req->r_result;
1412+ else
1413+ /*
1414+ * Writes aren't allowed to return a data payload. In some
1415+ * guarded write cases (e.g. stat + zero on an empty object)
1416+ * a stat response makes it through, but we don't care.
1417+ */
1418+ obj_req->xferred = 0;
18731419
1874− if (obj_request_done_test(obj_request))
1875− rbd_obj_request_complete(obj_request);
1420+ rbd_obj_handle_request(obj_req);
18761421 }
18771422
18781423 static void rbd_osd_req_format_read(struct rbd_obj_request *obj_request)
18791424 {
18801425 struct ceph_osd_request *osd_req = obj_request->osd_req;
18811426
1882− rbd_assert(obj_request_img_data_test(obj_request));
1427+ osd_req->r_flags = CEPH_OSD_FLAG_READ;
18831428 osd_req->r_snapid = obj_request->img_request->snap_id;
18841429 }
18851430
@@ -1887,32 +1432,33 @@ static void rbd_osd_req_format_write(struct rbd_obj_request *obj_request) · 1 unmodified line
18871432 {
18881433 struct ceph_osd_request *osd_req = obj_request->osd_req;
18891434
1435+ osd_req->r_flags = CEPH_OSD_FLAG_WRITE;
18901436 ktime_get_real_ts(&osd_req->r_mtime);
1891− osd_req->r_data_offset = obj_request->offset;
1437+ osd_req->r_data_offset = obj_request->ex.oe_off;
18921438 }
18931439
18941440 static struct ceph_osd_request *
1895−__rbd_osd_req_create(struct rbd_device *rbd_dev,
1896− struct ceph_snap_context *snapc,
1897− int num_ops, unsigned int flags,
1898− struct rbd_obj_request *obj_request)
1441+rbd_osd_req_create(struct rbd_obj_request *obj_req, unsigned int num_ops)
18991442 {
1443+ struct rbd_img_request *img_req = obj_req->img_request;
1444+ struct rbd_device *rbd_dev = img_req->rbd_dev;
19001445 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc;
19011446 struct ceph_osd_request *req;
19021447 const char *name_format = rbd_dev->image_format == 1 ?
19031448 RBD_V1_DATA_FORMAT : RBD_V2_DATA_FORMAT;
19041449
1905− req = ceph_osdc_alloc_request(osdc, snapc, num_ops, false, GFP_NOIO);
1450+ req = ceph_osdc_alloc_request(osdc,
1451+ (rbd_img_is_write(img_req) ? img_req->snapc : NULL),
1452+ num_ops, false, GFP_NOIO);
19061453 if (!req)
19071454 return NULL;
19081455
1909− req->r_flags = flags;
19101456 req->r_callback = rbd_osd_req_callback;
1911− req->r_priv = obj_request;
1457+ req->r_priv = obj_req;
19121458
19131459 req->r_base_oloc.pool = rbd_dev->layout.pool_id;
19141460 if (ceph_oid_aprintf(&req->r_base_oid, GFP_NOIO, name_format,
1915− rbd_dev->header.object_prefix, obj_request->object_no))
1461+ rbd_dev->header.object_prefix, obj_req->ex.oe_objno))
19161462 goto err_req;
19171463
19181464 if (ceph_osdc_alloc_messages(req, GFP_NOIO))
@@ -1925,83 +1471,20 @@ err_req: · 6 unmodified lines
19251471 return NULL;
19261472 }
19271473
1928−/*
1929− * Create an osd request. A read request has one osd op (read).
1930− * A write request has either one (watch) or two (hint+write) osd ops.
1931− * (All rbd data writes are prefixed with an allocation hint op, but
1932− * technically osd watch is a write request, hence this distinction.)
1933− */
1934−static struct ceph_osd_request *rbd_osd_req_create(
1935− struct rbd_device *rbd_dev,
1936− enum obj_operation_type op_type,
1937− unsigned int num_ops,
1938− struct rbd_obj_request *obj_request)
1939−{
1940− struct ceph_snap_context *snapc = NULL;
1941−
1942− if (obj_request_img_data_test(obj_request) &&
1943− (op_type == OBJ_OP_DISCARD || op_type == OBJ_OP_WRITE)) {
1944− struct rbd_img_request *img_request = obj_request->img_request;
1945− if (op_type == OBJ_OP_WRITE) {
1946− rbd_assert(img_request_write_test(img_request));
1947− } else {
1948− rbd_assert(img_request_discard_test(img_request));
1949− }
1950− snapc = img_request->snapc;
1951− }
1952−
1953− rbd_assert(num_ops == 1 || ((op_type == OBJ_OP_WRITE) && num_ops == 2));
1954−
1955− return __rbd_osd_req_create(rbd_dev, snapc, num_ops,
1956− (op_type == OBJ_OP_WRITE || op_type == OBJ_OP_DISCARD) ?
1957− CEPH_OSD_FLAG_WRITE : CEPH_OSD_FLAG_READ, obj_request);
1958−}
1959−
1960−/*
1961− * Create a copyup osd request based on the information in the object
1962− * request supplied. A copyup request has two or three osd ops, a
1963− * copyup method call, potentially a hint op, and a write or truncate
1964− * or zero op.
1965− */
1966−static struct ceph_osd_request *
1967−rbd_osd_req_create_copyup(struct rbd_obj_request *obj_request)
1968−{
1969− struct rbd_img_request *img_request;
1970− int num_osd_ops = 3;
1971−
1972− rbd_assert(obj_request_img_data_test(obj_request));
1973− img_request = obj_request->img_request;
1974− rbd_assert(img_request);
1975− rbd_assert(img_request_write_test(img_request) ||
1976− img_request_discard_test(img_request));
1977−
1978− if (img_request_discard_test(img_request))
1979− num_osd_ops = 2;
1980−
1981− return __rbd_osd_req_create(img_request->rbd_dev,
1982− img_request->snapc, num_osd_ops,
1983− CEPH_OSD_FLAG_WRITE, obj_request);
1984−}
1985−
19861474 static void rbd_osd_req_destroy(struct ceph_osd_request *osd_req)
19871475 {
19881476 ceph_osdc_put_request(osd_req);
19891477 }
19901478
1991−static struct rbd_obj_request *
1992−rbd_obj_request_create(enum obj_request_type type)
1479+static struct rbd_obj_request *rbd_obj_request_create(void)
19931480 {
19941481 struct rbd_obj_request *obj_request;
19951482
1996− rbd_assert(obj_request_type_valid(type));
1997−
19981483 obj_request = kmem_cache_zalloc(rbd_obj_request_cache, GFP_NOIO);
19991484 if (!obj_request)
20001485 return NULL;
20011486
2002− obj_request->which = BAD_WHICH;
2003− obj_request->type = type;
2004− INIT_LIST_HEAD(&obj_request->links);
1487+ ceph_object_extent_init(&obj_request->ex);
20051488 kref_init(&obj_request->kref);
20061489
20071490 dout("%s %p\n", __func__, obj_request);
@@ -2011,32 +1494,34 @@ rbd_obj_request_create(enum obj_request_type type) · 3 unmodified lines
20111494 static void rbd_obj_request_destroy(struct kref *kref)
20121495 {
20131496 struct rbd_obj_request *obj_request;
1497+ u32 i;
20141498
20151499 obj_request = container_of(kref, struct rbd_obj_request, kref);
20161500
20171501 dout("%s: obj %p\n", __func__, obj_request);
20181502
2019− rbd_assert(obj_request->img_request == NULL);
2020− rbd_assert(obj_request->which == BAD_WHICH);
2021−
20221503 if (obj_request->osd_req)
20231504 rbd_osd_req_destroy(obj_request->osd_req);
20241505
2025− rbd_assert(obj_request_type_valid(obj_request->type));
2026− switch (obj_request->type) {
1506+ switch (obj_request->img_request->data_type) {
20271507 case OBJ_REQUEST_NODATA:
2028− break; /* Nothing to do */
20291508 case OBJ_REQUEST_BIO:
2030− if (obj_request->bio_list)
2031− bio_chain_put(obj_request->bio_list);
2032− break;
2033− case OBJ_REQUEST_PAGES:
2034− /* img_data requests don't own their page array */
2035− if (obj_request->pages &&
2036− !obj_request_img_data_test(obj_request))
2037− ceph_release_page_vector(obj_request->pages,
2038− obj_request->page_count);
1509+ case OBJ_REQUEST_BVECS:
1510+ break; /* Nothing to do */
1511+ case OBJ_REQUEST_OWN_BVECS:
1512+ kfree(obj_request->bvec_pos.bvecs);
20391513 break;
1514+ default:
1515+ rbd_assert(0);
1516+ }
1517+
1518+ kfree(obj_request->img_extents);
1519+ if (obj_request->copyup_bvecs) {
1520+ for (i = 0; i < obj_request->copyup_bvec_count; i++) {
1521+ if (obj_request->copyup_bvecs[i].bv_page)
1522+ __free_page(obj_request->copyup_bvecs[i].bv_page);
1523+ }
1524+ kfree(obj_request->copyup_bvecs);
20401525 }
20411526
20421527 kmem_cache_free(rbd_obj_request_cache, obj_request);
@@ -2111,7 +1596,6 @@ static bool rbd_dev_parent_get(struct rbd_device *rbd_dev) · 68 unmodified lines
21111596 */
21121597 static struct rbd_img_request *rbd_img_request_create(
21131598 struct rbd_device *rbd_dev,
2114− u64 offset, u64 length,
21151599 enum obj_operation_type op_type,
21161600 struct ceph_snap_context *snapc)
21171601 {
@@ -2122,27 +1606,21 @@ static struct rbd_img_request *rbd_img_request_create( · 4 unmodified lines
21221606 return NULL;
21231607
21241608 img_request->rbd_dev = rbd_dev;
2125− img_request->offset = offset;
2126− img_request->length = length;
2127− if (op_type == OBJ_OP_DISCARD) {
2128− img_request_discard_set(img_request);
2129− img_request->snapc = snapc;
2130− } else if (op_type == OBJ_OP_WRITE) {
2131− img_request_write_set(img_request);
2132− img_request->snapc = snapc;
2133− } else {
1609+ img_request->op_type = op_type;
1610+ if (!rbd_img_is_write(img_request))
21341611 img_request->snap_id = rbd_dev->spec->snap_id;
2135− }
1612+ else
1613+ img_request->snapc = snapc;
1614+
21361615 if (rbd_dev_parent_get(rbd_dev))
21371616 img_request_layered_set(img_request);
21381617
21391618 spin_lock_init(&img_request->completion_lock);
2140− INIT_LIST_HEAD(&img_request->obj_requests);
1619+ INIT_LIST_HEAD(&img_request->object_extents);
21411620 kref_init(&img_request->kref);
21421621
2143− dout("%s: rbd_dev %p %s %llu/%llu -> img %p\n", __func__, rbd_dev,
2144− obj_op_name(op_type), offset, length, img_request);
2145−
1622+ dout("%s: rbd_dev %p %s -> img %p\n", __func__, rbd_dev,
1623+ obj_op_name(op_type), img_request);
21461624 return img_request;
21471625 }
21481626
@@ -2165,829 +1643,934 @@ static void rbd_img_request_destroy(struct kref *kref) · 16 unmodified lines
21651643 rbd_dev_parent_put(img_request->rbd_dev);
21661644 }
21671645
2168− if (img_request_write_test(img_request) ||
2169− img_request_discard_test(img_request))
1646+ if (rbd_img_is_write(img_request))
21701647 ceph_put_snap_context(img_request->snapc);
21711648
21721649 kmem_cache_free(rbd_img_request_cache, img_request);
21731650 }
21741651
2175−static struct rbd_img_request *rbd_parent_request_create(
2176− struct rbd_obj_request *obj_request,
2177− u64 img_offset, u64 length)
1652+static void prune_extents(struct ceph_file_extent *img_extents,
1653+ u32 *num_img_extents, u64 overlap)
21781654 {
2179− struct rbd_img_request *parent_request;
2180− struct rbd_device *rbd_dev;
1655+ u32 cnt = *num_img_extents;
21811656
2182− rbd_assert(obj_request->img_request);
2183− rbd_dev = obj_request->img_request->rbd_dev;
1657+ /* drop extents completely beyond the overlap */
1658+ while (cnt && img_extents[cnt - 1].fe_off >= overlap)
1659+ cnt--;
21841660
2185− parent_request = rbd_img_request_create(rbd_dev->parent, img_offset,
2186− length, OBJ_OP_READ, NULL);
2187− if (!parent_request)
2188− return NULL;
1661+ if (cnt) {
1662+ struct ceph_file_extent *ex = &img_extents[cnt - 1];
21891663
2190− img_request_child_set(parent_request);
2191− rbd_obj_request_get(obj_request);
2192− parent_request->obj_request = obj_request;
1664+ /* trim final overlapping extent */
1665+ if (ex->fe_off + ex->fe_len > overlap)
1666+ ex->fe_len = overlap - ex->fe_off;
1667+ }
21931668
2194− return parent_request;
1669+ *num_img_extents = cnt;
21951670 }
21961671
2197−static void rbd_parent_request_destroy(struct kref *kref)
1672+/*
1673+ * Determine the byte range(s) covered by either just the object extent
1674+ * or the entire object in the parent image.
1675+ */
1676+static int rbd_obj_calc_img_extents(struct rbd_obj_request *obj_req,
1677+ bool entire)
21981678 {
2199− struct rbd_img_request *parent_request;
2200− struct rbd_obj_request *orig_request;
1679+ struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev;
1680+ int ret;
22011681
2202− parent_request = container_of(kref, struct rbd_img_request, kref);
2203− orig_request = parent_request->obj_request;
1682+ if (!rbd_dev->parent_overlap)
1683+ return 0;
22041684
2205− parent_request->obj_request = NULL;
2206− rbd_obj_request_put(orig_request);
2207− img_request_child_clear(parent_request);
1685+ ret = ceph_extent_to_file(&rbd_dev->layout, obj_req->ex.oe_objno,
1686+ entire ? 0 : obj_req->ex.oe_off,
1687+ entire ? rbd_dev->layout.object_size :
1688+ obj_req->ex.oe_len,
1689+ &obj_req->img_extents,
1690+ &obj_req->num_img_extents);
1691+ if (ret)
1692+ return ret;
22081693
2209− rbd_img_request_destroy(kref);
1694+ prune_extents(obj_req->img_extents, &obj_req->num_img_extents,
1695+ rbd_dev->parent_overlap);
1696+ return 0;
22101697 }
22111698
2212−static bool rbd_img_obj_end_request(struct rbd_obj_request *obj_request)
1699+static void rbd_osd_req_setup_data(struct rbd_obj_request *obj_req, u32 which)
22131700 {
2214− struct rbd_img_request *img_request;
2215− unsigned int xferred;
2216− int result;
2217− bool more;
2218−
2219− rbd_assert(obj_request_img_data_test(obj_request));
2220− img_request = obj_request->img_request;
2221−
2222− rbd_assert(obj_request->xferred <= (u64)UINT_MAX);
2223− xferred = (unsigned int)obj_request->xferred;
2224− result = obj_request->result;
2225− if (result) {
2226− struct rbd_device *rbd_dev = img_request->rbd_dev;
2227− enum obj_operation_type op_type;
2228−
2229− if (img_request_discard_test(img_request))
2230− op_type = OBJ_OP_DISCARD;
2231− else if (img_request_write_test(img_request))
2232− op_type = OBJ_OP_WRITE;
2233− else
2234− op_type = OBJ_OP_READ;
2235−
2236− rbd_warn(rbd_dev, "%s %llx at %llx (%llx)",
2237− obj_op_name(op_type), obj_request->length,
2238− obj_request->img_offset, obj_request->offset);
2239− rbd_warn(rbd_dev, " result %d xferred %x",
2240− result, xferred);
2241− if (!img_request->result)
2242− img_request->result = result;
2243− /*
2244− * Need to end I/O on the entire obj_request worth of
2245− * bytes in case of error.
2246− */
2247− xferred = obj_request->length;
1701+ switch (obj_req->img_request->data_type) {
1702+ case OBJ_REQUEST_BIO:
1703+ osd_req_op_extent_osd_data_bio(obj_req->osd_req, which,
1704+ &obj_req->bio_pos,
1705+ obj_req->ex.oe_len);
1706+ break;
1707+ case OBJ_REQUEST_BVECS:
1708+ case OBJ_REQUEST_OWN_BVECS:
1709+ rbd_assert(obj_req->bvec_pos.iter.bi_size ==
1710+ obj_req->ex.oe_len);
1711+ rbd_assert(obj_req->bvec_idx == obj_req->bvec_count);
1712+ osd_req_op_extent_osd_data_bvec_pos(obj_req->osd_req, which,
1713+ &obj_req->bvec_pos);
1714+ break;
1715+ default:
1716+ rbd_assert(0);
22481717 }
1718+}
22491719
2250− if (img_request_child_test(img_request)) {
2251− rbd_assert(img_request->obj_request != NULL);
2252− more = obj_request->which < img_request->obj_request_count - 1;
2253− } else {
2254− blk_status_t status = errno_to_blk_status(result);
1720+static int rbd_obj_setup_read(struct rbd_obj_request *obj_req)
1721+{
1722+ obj_req->osd_req = rbd_osd_req_create(obj_req, 1);
1723+ if (!obj_req->osd_req)
1724+ return -ENOMEM;
22551725
2256− rbd_assert(img_request->rq != NULL);
1726+ osd_req_op_extent_init(obj_req->osd_req, 0, CEPH_OSD_OP_READ,
1727+ obj_req->ex.oe_off, obj_req->ex.oe_len, 0, 0);
1728+ rbd_osd_req_setup_data(obj_req, 0);
22571729
2258− more = blk_update_request(img_request->rq, status, xferred);
2259− if (!more)
2260− __blk_mq_end_request(img_request->rq, status);
2261− }
1730+ rbd_osd_req_format_read(obj_req);
1731+ return 0;
1732+}
1733+
1734+static int __rbd_obj_setup_stat(struct rbd_obj_request *obj_req,
1735+ unsigned int which)
1736+{
1737+ struct page **pages;
22621738
2263− return more;
1739+ /*
1740+ * The response data for a STAT call consists of:
1741+ * le64 length;
1742+ * struct {
1743+ * le32 tv_sec;
1744+ * le32 tv_nsec;
1745+ * } mtime;
1746+ */
1747+ pages = ceph_alloc_page_vector(1, GFP_NOIO);
1748+ if (IS_ERR(pages))
1749+ return PTR_ERR(pages);
1750+
1751+ osd_req_op_init(obj_req->osd_req, which, CEPH_OSD_OP_STAT, 0);
1752+ osd_req_op_raw_data_in_pages(obj_req->osd_req, which, pages,
1753+ 8 + sizeof(struct ceph_timespec),
1754+ 0, false, true);
1755+ return 0;
22641756 }
22651757
2266−static void rbd_img_obj_callback(struct rbd_obj_request *obj_request)
1758+static void __rbd_obj_setup_write(struct rbd_obj_request *obj_req,
1759+ unsigned int which)
22671760 {
2268− struct rbd_img_request *img_request;
2269− u32 which = obj_request->which;
2270− bool more = true;
1761+ struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev;
1762+ u16 opcode;
22711763
2272− rbd_assert(obj_request_img_data_test(obj_request));
2273− img_request = obj_request->img_request;
1764+ osd_req_op_alloc_hint_init(obj_req->osd_req, which++,
1765+ rbd_dev->layout.object_size,
1766+ rbd_dev->layout.object_size);
22741767
2275− dout("%s: img %p obj %p\n", __func__, img_request, obj_request);
2276− rbd_assert(img_request != NULL);
2277− rbd_assert(img_request->obj_request_count > 0);
2278− rbd_assert(which != BAD_WHICH);
2279− rbd_assert(which < img_request->obj_request_count);
1768+ if (rbd_obj_is_entire(obj_req))
1769+ opcode = CEPH_OSD_OP_WRITEFULL;
1770+ else
1771+ opcode = CEPH_OSD_OP_WRITE;
22801772
2281− spin_lock_irq(&img_request->completion_lock);
2282− if (which != img_request->next_completion)
2283− goto out;
1773+ osd_req_op_extent_init(obj_req->osd_req, which, opcode,
1774+ obj_req->ex.oe_off, obj_req->ex.oe_len, 0, 0);
1775+ rbd_osd_req_setup_data(obj_req, which++);
22841776
2285− for_each_obj_request_from(img_request, obj_request) {
2286− rbd_assert(more);
2287− rbd_assert(which < img_request->obj_request_count);
1777+ rbd_assert(which == obj_req->osd_req->r_num_ops);
1778+ rbd_osd_req_format_write(obj_req);
1779+}
22881780
2289− if (!obj_request_done_test(obj_request))
2290− break;
2291− more = rbd_img_obj_end_request(obj_request);
2292− which++;
1781+static int rbd_obj_setup_write(struct rbd_obj_request *obj_req)
1782+{
1783+ unsigned int num_osd_ops, which = 0;
1784+ int ret;
1785+
1786+ /* reverse map the entire object onto the parent */
1787+ ret = rbd_obj_calc_img_extents(obj_req, true);
1788+ if (ret)
1789+ return ret;
1790+
1791+ if (obj_req->num_img_extents) {
1792+ obj_req->write_state = RBD_OBJ_WRITE_GUARD;
1793+ num_osd_ops = 3; /* stat + setallochint + write/writefull */
1794+ } else {
1795+ obj_req->write_state = RBD_OBJ_WRITE_FLAT;
1796+ num_osd_ops = 2; /* setallochint + write/writefull */
22931797 }
22941798
2295− rbd_assert(more ^ (which == img_request->obj_request_count));
2296− img_request->next_completion = which;
2297−out:
2298− spin_unlock_irq(&img_request->completion_lock);
2299− rbd_img_request_put(img_request);
1799+ obj_req->osd_req = rbd_osd_req_create(obj_req, num_osd_ops);
1800+ if (!obj_req->osd_req)
1801+ return -ENOMEM;
23001802
2301− if (!more)
2302− rbd_img_request_complete(img_request);
1803+ if (obj_req->num_img_extents) {
1804+ ret = __rbd_obj_setup_stat(obj_req, which++);
1805+ if (ret)
1806+ return ret;
1807+ }
1808+
1809+ __rbd_obj_setup_write(obj_req, which);
1810+ return 0;
23031811 }
23041812
2305−/*
2306− * Add individual osd ops to the given ceph_osd_request and prepare
2307− * them for submission. num_ops is the current number of
2308− * osd operations already to the object request.
2309− */
2310−static void rbd_img_obj_request_fill(struct rbd_obj_request *obj_request,
2311− struct ceph_osd_request *osd_request,
2312− enum obj_operation_type op_type,
2313− unsigned int num_ops)
2314−{
2315− struct rbd_img_request *img_request = obj_request->img_request;
2316− struct rbd_device *rbd_dev = img_request->rbd_dev;
2317− u64 object_size = rbd_obj_bytes(&rbd_dev->header);
2318− u64 offset = obj_request->offset;
2319− u64 length = obj_request->length;
2320− u64 img_end;
1813+static void __rbd_obj_setup_discard(struct rbd_obj_request *obj_req,
1814+ unsigned int which)
1815+{
23211816 u16 opcode;
23221817
2323− if (op_type == OBJ_OP_DISCARD) {
2324− if (!offset && length == object_size &&
2325− (!img_request_layered_test(img_request) ||
2326− !obj_request_overlaps_parent(obj_request))) {
2327− opcode = CEPH_OSD_OP_DELETE;
2328− } else if ((offset + length == object_size)) {
1818+ if (rbd_obj_is_entire(obj_req)) {
1819+ if (obj_req->num_img_extents) {
1820+ osd_req_op_init(obj_req->osd_req, which++,
1821+ CEPH_OSD_OP_CREATE, 0);
23291822 opcode = CEPH_OSD_OP_TRUNCATE;
23301823 } else {
2331− down_read(&rbd_dev->header_rwsem);
2332− img_end = rbd_dev->header.image_size;
2333− up_read(&rbd_dev->header_rwsem);
2334−
2335− if (obj_request->img_offset + length == img_end)
2336− opcode = CEPH_OSD_OP_TRUNCATE;
2337− else
2338− opcode = CEPH_OSD_OP_ZERO;
1824+ osd_req_op_init(obj_req->osd_req, which++,
1825+ CEPH_OSD_OP_DELETE, 0);
1826+ opcode = 0;
23391827 }
2340− } else if (op_type == OBJ_OP_WRITE) {
2341− if (!offset && length == object_size)
2342− opcode = CEPH_OSD_OP_WRITEFULL;
2343− else
2344− opcode = CEPH_OSD_OP_WRITE;
2345− osd_req_op_alloc_hint_init(osd_request, num_ops,
2346− object_size, object_size);
2347− num_ops++;
1828+ } else if (rbd_obj_is_tail(obj_req)) {
1829+ opcode = CEPH_OSD_OP_TRUNCATE;
23481830 } else {
2349− opcode = CEPH_OSD_OP_READ;
1831+ opcode = CEPH_OSD_OP_ZERO;
23501832 }
23511833
2352− if (opcode == CEPH_OSD_OP_DELETE)
2353− osd_req_op_init(osd_request, num_ops, opcode, 0);
2354− else
2355− osd_req_op_extent_init(osd_request, num_ops, opcode,
2356− offset, length, 0, 0);
2357−
2358− if (obj_request->type == OBJ_REQUEST_BIO)
2359− osd_req_op_extent_osd_data_bio(osd_request, num_ops,
2360− obj_request->bio_list, length);
2361− else if (obj_request->type == OBJ_REQUEST_PAGES)
2362− osd_req_op_extent_osd_data_pages(osd_request, num_ops,
2363− obj_request->pages, length,
2364− offset & ~PAGE_MASK, false, false);
2365−
2366− /* Discards are also writes */
2367− if (op_type == OBJ_OP_WRITE || op_type == OBJ_OP_DISCARD)
2368− rbd_osd_req_format_write(obj_request);
2369− else
2370− rbd_osd_req_format_read(obj_request);
1834+ if (opcode)
1835+ osd_req_op_extent_init(obj_req->osd_req, which++, opcode,
1836+ obj_req->ex.oe_off, obj_req->ex.oe_len,
1837+ 0, 0);
1838+
1839+ rbd_assert(which == obj_req->osd_req->r_num_ops);
1840+ rbd_osd_req_format_write(obj_req);
23711841 }
23721842
2373−/*
2374− * Split up an image request into one or more object requests, each
2375− * to a different object. The "type" parameter indicates whether
2376− * "data_desc" is the pointer to the head of a list of bio
2377− * structures, or the base of a page array. In either case this
2378− * function assumes data_desc describes memory sufficient to hold
2379− * all data described by the image request.
2380− */
2381−static int rbd_img_request_fill(struct rbd_img_request *img_request,
2382− enum obj_request_type type,
2383− void *data_desc)
1843+static int rbd_obj_setup_discard(struct rbd_obj_request *obj_req)
23841844 {
2385− struct rbd_device *rbd_dev = img_request->rbd_dev;
2386− struct rbd_obj_request *obj_request = NULL;
2387− struct rbd_obj_request *next_obj_request;
2388− struct bio *bio_list = NULL;
2389− unsigned int bio_offset = 0;
2390− struct page **pages = NULL;
2391− enum obj_operation_type op_type;
2392− u64 img_offset;
2393− u64 resid;
2394−
2395− dout("%s: img %p type %d data_desc %p\n", __func__, img_request,
2396− (int)type, data_desc);
1845+ unsigned int num_osd_ops, which = 0;
1846+ int ret;
23971847
2398− img_offset = img_request->offset;
2399− resid = img_request->length;
2400− rbd_assert(resid > 0);
2401− op_type = rbd_img_request_op_type(img_request);
1848+ /* reverse map the entire object onto the parent */
1849+ ret = rbd_obj_calc_img_extents(obj_req, true);
1850+ if (ret)
1851+ return ret;
24021852
2403− if (type == OBJ_REQUEST_BIO) {
2404− bio_list = data_desc;
2405− rbd_assert(img_offset ==
2406− bio_list->bi_iter.bi_sector << SECTOR_SHIFT);
2407− } else if (type == OBJ_REQUEST_PAGES) {
2408− pages = data_desc;
1853+ if (rbd_obj_is_entire(obj_req)) {
1854+ obj_req->write_state = RBD_OBJ_WRITE_FLAT;
1855+ if (obj_req->num_img_extents)
1856+ num_osd_ops = 2; /* create + truncate */
1857+ else
1858+ num_osd_ops = 1; /* delete */
1859+ } else {
1860+ if (obj_req->num_img_extents) {
1861+ obj_req->write_state = RBD_OBJ_WRITE_GUARD;
1862+ num_osd_ops = 2; /* stat + truncate/zero */
1863+ } else {
1864+ obj_req->write_state = RBD_OBJ_WRITE_FLAT;
1865+ num_osd_ops = 1; /* truncate/zero */
1866+ }
24091867 }
24101868
2411− while (resid) {
2412− struct ceph_osd_request *osd_req;
2413− u64 object_no = img_offset >> rbd_dev->header.obj_order;
2414− u64 offset = rbd_segment_offset(rbd_dev, img_offset);
2415− u64 length = rbd_segment_length(rbd_dev, img_offset, resid);
2416−
2417− obj_request = rbd_obj_request_create(type);
2418− if (!obj_request)
2419− goto out_unwind;
2420−
2421− obj_request->object_no = object_no;
2422− obj_request->offset = offset;
2423− obj_request->length = length;
2424−
2425− /*
2426− * set obj_request->img_request before creating the
2427− * osd_request so that it gets the right snapc
2428− */
2429− rbd_img_obj_request_add(img_request, obj_request);
2430−
2431− if (type == OBJ_REQUEST_BIO) {
2432− unsigned int clone_size;
2433−
2434− rbd_assert(length <= (u64)UINT_MAX);
2435− clone_size = (unsigned int)length;
2436− obj_request->bio_list =
2437− bio_chain_clone_range(&bio_list,
2438− &bio_offset,
2439− clone_size,
2440− GFP_NOIO);
2441− if (!obj_request->bio_list)
2442− goto out_unwind;
2443− } else if (type == OBJ_REQUEST_PAGES) {
2444− unsigned int page_count;
2445−
2446− obj_request->pages = pages;
2447− page_count = (u32)calc_pages_for(offset, length);
2448− obj_request->page_count = page_count;
2449− if ((offset + length) & ~PAGE_MASK)
2450− page_count--; /* more on last page */
2451− pages += page_count;
2452− }
1869+ obj_req->osd_req = rbd_osd_req_create(obj_req, num_osd_ops);
1870+ if (!obj_req->osd_req)
1871+ return -ENOMEM;
24531872
2454− osd_req = rbd_osd_req_create(rbd_dev, op_type,
2455− (op_type == OBJ_OP_WRITE) ? 2 : 1,
2456− obj_request);
2457− if (!osd_req)
2458− goto out_unwind;
1873+ if (!rbd_obj_is_entire(obj_req) && obj_req->num_img_extents) {
1874+ ret = __rbd_obj_setup_stat(obj_req, which++);
1875+ if (ret)
1876+ return ret;
1877+ }
24591878
2460− obj_request->osd_req = osd_req;
2461− obj_request->callback = rbd_img_obj_callback;
2462− obj_request->img_offset = img_offset;
1879+ __rbd_obj_setup_discard(obj_req, which);
1880+ return 0;
1881+}
24631882
2464− rbd_img_obj_request_fill(obj_request, osd_req, op_type, 0);
1883+/*
1884+ * For each object request in @img_req, allocate an OSD request, add
1885+ * individual OSD ops and prepare them for submission. The number of
1886+ * OSD ops depends on op_type and the overlap point (if any).
1887+ */
1888+static int __rbd_img_fill_request(struct rbd_img_request *img_req)
1889+{
1890+ struct rbd_obj_request *obj_req;
1891+ int ret;
24651892
2466− img_offset += length;
2467− resid -= length;
1893+ for_each_obj_request(img_req, obj_req) {
1894+ switch (img_req->op_type) {
1895+ case OBJ_OP_READ:
1896+ ret = rbd_obj_setup_read(obj_req);
1897+ break;
1898+ case OBJ_OP_WRITE:
1899+ ret = rbd_obj_setup_write(obj_req);
1900+ break;
1901+ case OBJ_OP_DISCARD:
1902+ ret = rbd_obj_setup_discard(obj_req);
1903+ break;
1904+ default:
1905+ rbd_assert(0);
1906+ }
1907+ if (ret)
1908+ return ret;
24681909 }
24691910
24701911 return 0;
1912+}
24711913
2472−out_unwind:
2473− for_each_obj_request_safe(img_request, obj_request, next_obj_request)
2474− rbd_img_obj_request_del(img_request, obj_request);
1914+union rbd_img_fill_iter {
1915+ struct ceph_bio_iter bio_iter;
1916+ struct ceph_bvec_iter bvec_iter;
1917+};
24751918
2476− return -ENOMEM;
2477−}
1919+struct rbd_img_fill_ctx {
1920+ enum obj_request_type pos_type;
1921+ union rbd_img_fill_iter *pos;
1922+ union rbd_img_fill_iter iter;
1923+ ceph_object_extent_fn_t set_pos_fn;
1924+ ceph_object_extent_fn_t count_fn;
1925+ ceph_object_extent_fn_t copy_fn;
1926+};
24781927
2479−static void
2480−rbd_osd_copyup_callback(struct rbd_obj_request *obj_request)
1928+static struct ceph_object_extent *alloc_object_extent(void *arg)
24811929 {
2482− struct rbd_img_request *img_request;
2483− struct rbd_device *rbd_dev;
2484− struct page **pages;
2485− u32 page_count;
1930+ struct rbd_img_request *img_req = arg;
1931+ struct rbd_obj_request *obj_req;
24861932
2487− dout("%s: obj %p\n", __func__, obj_request);
1933+ obj_req = rbd_obj_request_create();
1934+ if (!obj_req)
1935+ return NULL;
24881936
2489− rbd_assert(obj_request->type == OBJ_REQUEST_BIO ||
2490− obj_request->type == OBJ_REQUEST_NODATA);
2491− rbd_assert(obj_request_img_data_test(obj_request));
2492− img_request = obj_request->img_request;
2493− rbd_assert(img_request);
1937+ rbd_img_obj_request_add(img_req, obj_req);
1938+ return &obj_req->ex;
1939+}
24941940
2495− rbd_dev = img_request->rbd_dev;
2496− rbd_assert(rbd_dev);
1941+/*
1942+ * While su != os && sc == 1 is technically not fancy (it's the same
1943+ * layout as su == os && sc == 1), we can't use the nocopy path for it
1944+ * because ->set_pos_fn() should be called only once per object.
1945+ * ceph_file_to_extents() invokes action_fn once per stripe unit, so
1946+ * treat su != os && sc == 1 as fancy.
1947+ */
1948+static bool rbd_layout_is_fancy(struct ceph_file_layout *l)
1949+{
1950+ return l->stripe_unit != l->object_size;
1951+}
24971952
2498− pages = obj_request->copyup_pages;
2499− rbd_assert(pages != NULL);
2500− obj_request->copyup_pages = NULL;
2501− page_count = obj_request->copyup_page_count;
2502− rbd_assert(page_count);
2503− obj_request->copyup_page_count = 0;
2504− ceph_release_page_vector(pages, page_count);
1953+static int rbd_img_fill_request_nocopy(struct rbd_img_request *img_req,
1954+ struct ceph_file_extent *img_extents,
1955+ u32 num_img_extents,
1956+ struct rbd_img_fill_ctx *fctx)
1957+{
1958+ u32 i;
1959+ int ret;
1960+
1961+ img_req->data_type = fctx->pos_type;
25051962
25061963 /*
2507− * We want the transfer count to reflect the size of the
2508− * original write request. There is no such thing as a
2509− * successful short write, so if the request was successful
2510− * we can just set it to the originally-requested length.
1964+ * Create object requests and set each object request's starting
1965+ * position in the provided bio (list) or bio_vec array.
25111966 */
2512− if (!obj_request->result)
2513− obj_request->xferred = obj_request->length;
1967+ fctx->iter = *fctx->pos;
1968+ for (i = 0; i < num_img_extents; i++) {
1969+ ret = ceph_file_to_extents(&img_req->rbd_dev->layout,
1970+ img_extents[i].fe_off,
1971+ img_extents[i].fe_len,
1972+ &img_req->object_extents,
1973+ alloc_object_extent, img_req,
1974+ fctx->set_pos_fn, &fctx->iter);
1975+ if (ret)
1976+ return ret;
1977+ }
25141978
2515− obj_request_done_set(obj_request);
1979+ return __rbd_img_fill_request(img_req);
25161980 }
25171981
2518−static void
2519−rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request)
1982+/*
1983+ * Map a list of image extents to a list of object extents, create the
1984+ * corresponding object requests (normally each to a different object,
1985+ * but not always) and add them to @img_req. For each object request,
1986+ * set up its data descriptor to point to the corresponding chunk(s) of
1987+ * @fctx->pos data buffer.
1988+ *
1989+ * Because ceph_file_to_extents() will merge adjacent object extents
1990+ * together, each object request's data descriptor may point to multiple
1991+ * different chunks of @fctx->pos data buffer.
1992+ *
1993+ * @fctx->pos data buffer is assumed to be large enough.
1994+ */
1995+static int rbd_img_fill_request(struct rbd_img_request *img_req,
1996+ struct ceph_file_extent *img_extents,
1997+ u32 num_img_extents,
1998+ struct rbd_img_fill_ctx *fctx)
25201999 {
2521− struct rbd_obj_request *orig_request;
2522− struct ceph_osd_request *osd_req;
2523− struct rbd_device *rbd_dev;
2524− struct page **pages;
2525− enum obj_operation_type op_type;
2526− u32 page_count;
2527− int img_result;
2528− u64 parent_length;
2529−
2530− rbd_assert(img_request_child_test(img_request));
2531−
2532− /* First get what we need from the image request */
2533−
2534− pages = img_request->copyup_pages;
2535− rbd_assert(pages != NULL);
2536− img_request->copyup_pages = NULL;
2537− page_count = img_request->copyup_page_count;
2538− rbd_assert(page_count);
2539− img_request->copyup_page_count = 0;
2540−
2541− orig_request = img_request->obj_request;
2542− rbd_assert(orig_request != NULL);
2543− rbd_assert(obj_request_type_valid(orig_request->type));
2544− img_result = img_request->result;
2545− parent_length = img_request->length;
2546− rbd_assert(img_result || parent_length == img_request->xferred);
2547− rbd_img_request_put(img_request);
2000+ struct rbd_device *rbd_dev = img_req->rbd_dev;
2001+ struct rbd_obj_request *obj_req;
2002+ u32 i;
2003+ int ret;
2004+
2005+ if (fctx->pos_type == OBJ_REQUEST_NODATA ||
2006+ !rbd_layout_is_fancy(&rbd_dev->layout))
2007+ return rbd_img_fill_request_nocopy(img_req, img_extents,
2008+ num_img_extents, fctx);
25482009
2549− rbd_assert(orig_request->img_request);
2550− rbd_dev = orig_request->img_request->rbd_dev;
2551− rbd_assert(rbd_dev);
2010+ img_req->data_type = OBJ_REQUEST_OWN_BVECS;
25522011
25532012 /*
2554− * If the overlap has become 0 (most likely because the
2555− * image has been flattened) we need to free the pages
2556− * and re-submit the original write request.
2013+ * Create object requests and determine ->bvec_count for each object
2014+ * request. Note that ->bvec_count sum over all object requests may
2015+ * be greater than the number of bio_vecs in the provided bio (list)
2016+ * or bio_vec array because when mapped, those bio_vecs can straddle
2017+ * stripe unit boundaries.
25572018 */
2558− if (!rbd_dev->parent_overlap) {
2559− ceph_release_page_vector(pages, page_count);
2560− rbd_obj_request_submit(orig_request);
2561− return;
2019+ fctx->iter = *fctx->pos;
2020+ for (i = 0; i < num_img_extents; i++) {
2021+ ret = ceph_file_to_extents(&rbd_dev->layout,
2022+ img_extents[i].fe_off,
2023+ img_extents[i].fe_len,
2024+ &img_req->object_extents,
2025+ alloc_object_extent, img_req,
2026+ fctx->count_fn, &fctx->iter);
2027+ if (ret)
2028+ return ret;
25622029 }
25632030
2564− if (img_result)
2565− goto out_err;
2031+ for_each_obj_request(img_req, obj_req) {
2032+ obj_req->bvec_pos.bvecs = kmalloc_array(obj_req->bvec_count,
2033+ sizeof(*obj_req->bvec_pos.bvecs),
2034+ GFP_NOIO);
2035+ if (!obj_req->bvec_pos.bvecs)
2036+ return -ENOMEM;
2037+ }
25662038
25672039 /*
2568− * The original osd request is of no use to use any more.
2569− * We need a new one that can hold the three ops in a copyup
2570− * request. Allocate the new copyup osd request for the
2571− * original request, and release the old one.
2040+ * Fill in each object request's private bio_vec array, splitting and
2041+ * rearranging the provided bio_vecs in stripe unit chunks as needed.
25722042 */
2573− img_result = -ENOMEM;
2574− osd_req = rbd_osd_req_create_copyup(orig_request);
2575− if (!osd_req)
2576− goto out_err;
2577− rbd_osd_req_destroy(orig_request->osd_req);
2578− orig_request->osd_req = osd_req;
2579− orig_request->copyup_pages = pages;
2580− orig_request->copyup_page_count = page_count;
2043+ fctx->iter = *fctx->pos;
2044+ for (i = 0; i < num_img_extents; i++) {
2045+ ret = ceph_iterate_extents(&rbd_dev->layout,
2046+ img_extents[i].fe_off,
2047+ img_extents[i].fe_len,
2048+ &img_req->object_extents,
2049+ fctx->copy_fn, &fctx->iter);
2050+ if (ret)
2051+ return ret;
2052+ }
25812053
2582− /* Initialize the copyup op */
2054+ return __rbd_img_fill_request(img_req);
2055+}
2056+
2057+static int rbd_img_fill_nodata(struct rbd_img_request *img_req,
2058+ u64 off, u64 len)
2059+{
2060+ struct ceph_file_extent ex = { off, len };
2061+ union rbd_img_fill_iter dummy;
2062+ struct rbd_img_fill_ctx fctx = {
2063+ .pos_type = OBJ_REQUEST_NODATA,
2064+ .pos = &dummy,
2065+ };
2066+
2067+ return rbd_img_fill_request(img_req, &ex, 1, &fctx);
2068+}
2069+
2070+static void set_bio_pos(struct ceph_object_extent *ex, u32 bytes, void *arg)
2071+{
2072+ struct rbd_obj_request *obj_req =
2073+ container_of(ex, struct rbd_obj_request, ex);
2074+ struct ceph_bio_iter *it = arg;
25832075
2584− osd_req_op_cls_init(osd_req, 0, CEPH_OSD_OP_CALL, "rbd", "copyup");
2585− osd_req_op_cls_request_data_pages(osd_req, 0, pages, parent_length, 0,
2586− false, false);
2076+ dout("%s objno %llu bytes %u\n", __func__, ex->oe_objno, bytes);
2077+ obj_req->bio_pos = *it;
2078+ ceph_bio_iter_advance(it, bytes);
2079+}
25872080
2588− /* Add the other op(s) */
2081+static void count_bio_bvecs(struct ceph_object_extent *ex, u32 bytes, void *arg)
2082+{
2083+ struct rbd_obj_request *obj_req =
2084+ container_of(ex, struct rbd_obj_request, ex);
2085+ struct ceph_bio_iter *it = arg;
25892086
2590− op_type = rbd_img_request_op_type(orig_request->img_request);
2591− rbd_img_obj_request_fill(orig_request, osd_req, op_type, 1);
2087+ dout("%s objno %llu bytes %u\n", __func__, ex->oe_objno, bytes);
2088+ ceph_bio_iter_advance_step(it, bytes, ({
2089+ obj_req->bvec_count++;
2090+ }));
25922091
2593− /* All set, send it off. */
2092+}
25942093
2595− rbd_obj_request_submit(orig_request);
2596− return;
2094+static void copy_bio_bvecs(struct ceph_object_extent *ex, u32 bytes, void *arg)
2095+{
2096+ struct rbd_obj_request *obj_req =
2097+ container_of(ex, struct rbd_obj_request, ex);
2098+ struct ceph_bio_iter *it = arg;
25972099
2598−out_err:
2599− ceph_release_page_vector(pages, page_count);
2600− rbd_obj_request_error(orig_request, img_result);
2100+ dout("%s objno %llu bytes %u\n", __func__, ex->oe_objno, bytes);
2101+ ceph_bio_iter_advance_step(it, bytes, ({
2102+ obj_req->bvec_pos.bvecs[obj_req->bvec_idx++] = bv;
2103+ obj_req->bvec_pos.iter.bi_size += bv.bv_len;
2104+ }));
26012105 }
26022106
2603−/*
2604− * Read from the parent image the range of data that covers the
2605− * entire target of the given object request. This is used for
2606− * satisfying a layered image write request when the target of an
2607− * object request from the image request does not exist.
2608− *
2609− * A page array big enough to hold the returned data is allocated
2610− * and supplied to rbd_img_request_fill() as the "data descriptor."
2611− * When the read completes, this page array will be transferred to
2612− * the original object request for the copyup operation.
2613− *
2614− * If an error occurs, it is recorded as the result of the original
2615− * object request in rbd_img_obj_exists_callback().
2616− */
2617−static int rbd_img_obj_parent_read_full(struct rbd_obj_request *obj_request)
2618−{
2619− struct rbd_device *rbd_dev = obj_request->img_request->rbd_dev;
2620− struct rbd_img_request *parent_request = NULL;
2621− u64 img_offset;
2622− u64 length;
2623− struct page **pages = NULL;
2624− u32 page_count;
2625− int result;
2107+static int __rbd_img_fill_from_bio(struct rbd_img_request *img_req,
2108+ struct ceph_file_extent *img_extents,
2109+ u32 num_img_extents,
2110+ struct ceph_bio_iter *bio_pos)
2111+{
2112+ struct rbd_img_fill_ctx fctx = {
2113+ .pos_type = OBJ_REQUEST_BIO,
2114+ .pos = (union rbd_img_fill_iter *)bio_pos,
2115+ .set_pos_fn = set_bio_pos,
2116+ .count_fn = count_bio_bvecs,
2117+ .copy_fn = copy_bio_bvecs,
2118+ };
26262119
2627− rbd_assert(rbd_dev->parent != NULL);
2120+ return rbd_img_fill_request(img_req, img_extents, num_img_extents,
2121+ &fctx);
2122+}
26282123
2629− /*
2630− * Determine the byte range covered by the object in the
2631− * child image to which the original request was to be sent.
2632− */
2633− img_offset = obj_request->img_offset - obj_request->offset;
2634− length = rbd_obj_bytes(&rbd_dev->header);
2124+static int rbd_img_fill_from_bio(struct rbd_img_request *img_req,
2125+ u64 off, u64 len, struct bio *bio)
2126+{
2127+ struct ceph_file_extent ex = { off, len };
2128+ struct ceph_bio_iter it = { .bio = bio, .iter = bio->bi_iter };
26352129
2636− /*
2637− * There is no defined parent data beyond the parent
2638− * overlap, so limit what we read at that boundary if
2639− * necessary.
2640− */
2641− if (img_offset + length > rbd_dev->parent_overlap) {
2642− rbd_assert(img_offset < rbd_dev->parent_overlap);
2643− length = rbd_dev->parent_overlap - img_offset;
2644− }
2130+ return __rbd_img_fill_from_bio(img_req, &ex, 1, &it);
2131+}
26452132
2646− /*
2647− * Allocate a page array big enough to receive the data read
2648− * from the parent.
2649− */
2650− page_count = (u32)calc_pages_for(0, length);
2651− pages = ceph_alloc_page_vector(page_count, GFP_NOIO);
2652− if (IS_ERR(pages)) {
2653− result = PTR_ERR(pages);
2654− pages = NULL;
2655− goto out_err;
2656− }
2133+static void set_bvec_pos(struct ceph_object_extent *ex, u32 bytes, void *arg)
2134+{
2135+ struct rbd_obj_request *obj_req =
2136+ container_of(ex, struct rbd_obj_request, ex);
2137+ struct ceph_bvec_iter *it = arg;
26572138
2658− result = -ENOMEM;
2659− parent_request = rbd_parent_request_create(obj_request,
2660− img_offset, length);
2661− if (!parent_request)
2662− goto out_err;
2139+ obj_req->bvec_pos = *it;
2140+ ceph_bvec_iter_shorten(&obj_req->bvec_pos, bytes);
2141+ ceph_bvec_iter_advance(it, bytes);
2142+}
26632143
2664− result = rbd_img_request_fill(parent_request, OBJ_REQUEST_PAGES, pages);
2665− if (result)
2666− goto out_err;
2144+static void count_bvecs(struct ceph_object_extent *ex, u32 bytes, void *arg)
2145+{
2146+ struct rbd_obj_request *obj_req =
2147+ container_of(ex, struct rbd_obj_request, ex);
2148+ struct ceph_bvec_iter *it = arg;
26672149
2668− parent_request->copyup_pages = pages;
2669− parent_request->copyup_page_count = page_count;
2670− parent_request->callback = rbd_img_obj_parent_read_full_callback;
2150+ ceph_bvec_iter_advance_step(it, bytes, ({
2151+ obj_req->bvec_count++;
2152+ }));
2153+}
26712154
2672− result = rbd_img_request_submit(parent_request);
2673− if (!result)
2674− return 0;
2155+static void copy_bvecs(struct ceph_object_extent *ex, u32 bytes, void *arg)
2156+{
2157+ struct rbd_obj_request *obj_req =
2158+ container_of(ex, struct rbd_obj_request, ex);
2159+ struct ceph_bvec_iter *it = arg;
26752160
2676− parent_request->copyup_pages = NULL;
2677− parent_request->copyup_page_count = 0;
2678−out_err:
2679− if (pages)
2680− ceph_release_page_vector(pages, page_count);
2681− if (parent_request)
2682− rbd_img_request_put(parent_request);
2683− return result;
2161+ ceph_bvec_iter_advance_step(it, bytes, ({
2162+ obj_req->bvec_pos.bvecs[obj_req->bvec_idx++] = bv;
2163+ obj_req->bvec_pos.iter.bi_size += bv.bv_len;
2164+ }));
26842165 }
26852166
2686−static void rbd_img_obj_exists_callback(struct rbd_obj_request *obj_request)
2167+static int __rbd_img_fill_from_bvecs(struct rbd_img_request *img_req,
2168+ struct ceph_file_extent *img_extents,
2169+ u32 num_img_extents,
2170+ struct ceph_bvec_iter *bvec_pos)
26872171 {
2688− struct rbd_obj_request *orig_request;
2689− struct rbd_device *rbd_dev;
2690− int result;
2172+ struct rbd_img_fill_ctx fctx = {
2173+ .pos_type = OBJ_REQUEST_BVECS,
2174+ .pos = (union rbd_img_fill_iter *)bvec_pos,
2175+ .set_pos_fn = set_bvec_pos,
2176+ .count_fn = count_bvecs,
2177+ .copy_fn = copy_bvecs,
2178+ };
26912179
2692− rbd_assert(!obj_request_img_data_test(obj_request));
2180+ return rbd_img_fill_request(img_req, img_extents, num_img_extents,
2181+ &fctx);
2182+}
26932183
2694− /*
2695− * All we need from the object request is the original
2696− * request and the result of the STAT op. Grab those, then
2697− * we're done with the request.
2698− */
2699− orig_request = obj_request->obj_request;
2700− obj_request->obj_request = NULL;
2701− rbd_obj_request_put(orig_request);
2702− rbd_assert(orig_request);
2703− rbd_assert(orig_request->img_request);
2704−
2705− result = obj_request->result;
2706− obj_request->result = 0;
2707−
2708− dout("%s: obj %p for obj %p result %d %llu/%llu\n", __func__,
2709− obj_request, orig_request, result,
2710− obj_request->xferred, obj_request->length);
2711− rbd_obj_request_put(obj_request);
2184+static int rbd_img_fill_from_bvecs(struct rbd_img_request *img_req,
2185+ struct ceph_file_extent *img_extents,
2186+ u32 num_img_extents,
2187+ struct bio_vec *bvecs)
2188+{
2189+ struct ceph_bvec_iter it = {
2190+ .bvecs = bvecs,
2191+ .iter = { .bi_size = ceph_file_extents_bytes(img_extents,
2192+ num_img_extents) },
2193+ };
27122194
2713− /*
2714− * If the overlap has become 0 (most likely because the
2715− * image has been flattened) we need to re-submit the
2716− * original request.
2717− */
2718− rbd_dev = orig_request->img_request->rbd_dev;
2719− if (!rbd_dev->parent_overlap) {
2720− rbd_obj_request_submit(orig_request);
2721− return;
2722− }
2195+ return __rbd_img_fill_from_bvecs(img_req, img_extents, num_img_extents,
2196+ &it);
2197+}
27232198
2724− /*
2725− * Our only purpose here is to determine whether the object
2726− * exists, and we don't want to treat the non-existence as
2727− * an error. If something else comes back, transfer the
2728− * error to the original request and complete it now.
2729− */
2730− if (!result) {
2731− obj_request_existence_set(orig_request, true);
2732− } else if (result == -ENOENT) {
2733− obj_request_existence_set(orig_request, false);
2734− } else {
2735− goto fail_orig_request;
2736− }
2199+static void rbd_img_request_submit(struct rbd_img_request *img_request)
2200+{
2201+ struct rbd_obj_request *obj_request;
27372202
2738− /*
2739− * Resubmit the original request now that we have recorded
2740− * whether the target object exists.
2741− */
2742− result = rbd_img_obj_request_submit(orig_request);
2743− if (result)
2744− goto fail_orig_request;
2203+ dout("%s: img %p\n", __func__, img_request);
27452204
2746− return;
2205+ rbd_img_request_get(img_request);
2206+ for_each_obj_request(img_request, obj_request)
2207+ rbd_obj_request_submit(obj_request);
27472208
2748−fail_orig_request:
2749− rbd_obj_request_error(orig_request, result);
2209+ rbd_img_request_put(img_request);
27502210 }
27512211
2752−static int rbd_img_obj_exists_submit(struct rbd_obj_request *obj_request)
2212+static int rbd_obj_read_from_parent(struct rbd_obj_request *obj_req)
27532213 {
2754− struct rbd_device *rbd_dev = obj_request->img_request->rbd_dev;
2755− struct rbd_obj_request *stat_request;
2756− struct page **pages;
2757− u32 page_count;
2758− size_t size;
2214+ struct rbd_img_request *img_req = obj_req->img_request;
2215+ struct rbd_img_request *child_img_req;
27592216 int ret;
27602217
2761− stat_request = rbd_obj_request_create(OBJ_REQUEST_PAGES);
2762− if (!stat_request)
2218+ child_img_req = rbd_img_request_create(img_req->rbd_dev->parent,
2219+ OBJ_OP_READ, NULL);
2220+ if (!child_img_req)
27632221 return -ENOMEM;
27642222
2765− stat_request->object_no = obj_request->object_no;
2223+ __set_bit(IMG_REQ_CHILD, &child_img_req->flags);
2224+ child_img_req->obj_request = obj_req;
27662225
2767− stat_request->osd_req = rbd_osd_req_create(rbd_dev, OBJ_OP_READ, 1,
2768− stat_request);
2769− if (!stat_request->osd_req) {
2770− ret = -ENOMEM;
2771− goto fail_stat_request;
2226+ if (!rbd_img_is_write(img_req)) {
2227+ switch (img_req->data_type) {
2228+ case OBJ_REQUEST_BIO:
2229+ ret = __rbd_img_fill_from_bio(child_img_req,
2230+ obj_req->img_extents,
2231+ obj_req->num_img_extents,
2232+ &obj_req->bio_pos);
2233+ break;
2234+ case OBJ_REQUEST_BVECS:
2235+ case OBJ_REQUEST_OWN_BVECS:
2236+ ret = __rbd_img_fill_from_bvecs(child_img_req,
2237+ obj_req->img_extents,
2238+ obj_req->num_img_extents,
2239+ &obj_req->bvec_pos);
2240+ break;
2241+ default:
2242+ rbd_assert(0);
2243+ }
2244+ } else {
2245+ ret = rbd_img_fill_from_bvecs(child_img_req,
2246+ obj_req->img_extents,
2247+ obj_req->num_img_extents,
2248+ obj_req->copyup_bvecs);
2249+ }
2250+ if (ret) {
2251+ rbd_img_request_put(child_img_req);
2252+ return ret;
2253+ }
2254+
2255+ rbd_img_request_submit(child_img_req);
2256+ return 0;
2257+}
2258+
2259+static bool rbd_obj_handle_read(struct rbd_obj_request *obj_req)
2260+{
2261+ struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev;
2262+ int ret;
2263+
2264+ if (obj_req->result == -ENOENT &&
2265+ rbd_dev->parent_overlap && !obj_req->tried_parent) {
2266+ /* reverse map this object extent onto the parent */
2267+ ret = rbd_obj_calc_img_extents(obj_req, false);
2268+ if (ret) {
2269+ obj_req->result = ret;
2270+ return true;
2271+ }
2272+
2273+ if (obj_req->num_img_extents) {
2274+ obj_req->tried_parent = true;
2275+ ret = rbd_obj_read_from_parent(obj_req);
2276+ if (ret) {
2277+ obj_req->result = ret;
2278+ return true;
2279+ }
2280+ return false;
2281+ }
27722282 }
27732283
27742284 /*
2775− * The response data for a STAT call consists of:
2776− * le64 length;
2777− * struct {
2778− * le32 tv_sec;
2779− * le32 tv_nsec;
2780− * } mtime;
2285+ * -ENOENT means a hole in the image -- zero-fill the entire
2286+ * length of the request. A short read also implies zero-fill
2287+ * to the end of the request. In both cases we update xferred
2288+ * count to indicate the whole request was satisfied.
27812289 */
2782− size = sizeof (__le64) + sizeof (__le32) + sizeof (__le32);
2783− page_count = (u32)calc_pages_for(0, size);
2784− pages = ceph_alloc_page_vector(page_count, GFP_NOIO);
2785− if (IS_ERR(pages)) {
2786− ret = PTR_ERR(pages);
2787− goto fail_stat_request;
2290+ if (obj_req->result == -ENOENT ||
2291+ (!obj_req->result && obj_req->xferred < obj_req->ex.oe_len)) {
2292+ rbd_assert(!obj_req->xferred || !obj_req->result);
2293+ rbd_obj_zero_range(obj_req, obj_req->xferred,
2294+ obj_req->ex.oe_len - obj_req->xferred);
2295+ obj_req->result = 0;
2296+ obj_req->xferred = obj_req->ex.oe_len;
27882297 }
27892298
2790− osd_req_op_init(stat_request->osd_req, 0, CEPH_OSD_OP_STAT, 0);
2791− osd_req_op_raw_data_in_pages(stat_request->osd_req, 0, pages, size, 0,
2792− false, false);
2793−
2794− rbd_obj_request_get(obj_request);
2795− stat_request->obj_request = obj_request;
2796− stat_request->pages = pages;
2797− stat_request->page_count = page_count;
2798− stat_request->callback = rbd_img_obj_exists_callback;
2299+ return true;
2300+}
27992301
2800− rbd_obj_request_submit(stat_request);
2801− return 0;
2302+/*
2303+ * copyup_bvecs pages are never highmem pages
2304+ */
2305+static bool is_zero_bvecs(struct bio_vec *bvecs, u32 bytes)
2306+{
2307+ struct ceph_bvec_iter it = {
2308+ .bvecs = bvecs,
2309+ .iter = { .bi_size = bytes },
2310+ };
28022311
2803−fail_stat_request:
2804− rbd_obj_request_put(stat_request);
2805− return ret;
2312+ ceph_bvec_iter_advance_step(&it, bytes, ({
2313+ if (memchr_inv(page_address(bv.bv_page) + bv.bv_offset, 0,
2314+ bv.bv_len))
2315+ return false;
2316+ }));
2317+ return true;
28062318 }
28072319
2808−static bool img_obj_request_simple(struct rbd_obj_request *obj_request)
2320+static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes)
28092321 {
2810− struct rbd_img_request *img_request = obj_request->img_request;
2811− struct rbd_device *rbd_dev = img_request->rbd_dev;
2812−
2813− /* Reads */
2814− if (!img_request_write_test(img_request) &&
2815− !img_request_discard_test(img_request))
2816− return true;
2322+ unsigned int num_osd_ops = obj_req->osd_req->r_num_ops;
28172323
2818− /* Non-layered writes */
2819− if (!img_request_layered_test(img_request))
2820− return true;
2324+ dout("%s obj_req %p bytes %u\n", __func__, obj_req, bytes);
2325+ rbd_assert(obj_req->osd_req->r_ops[0].op == CEPH_OSD_OP_STAT);
2326+ rbd_osd_req_destroy(obj_req->osd_req);
28212327
28222328 /*
2823− * Layered writes outside of the parent overlap range don't
2824− * share any data with the parent.
2329+ * Create a copyup request with the same number of OSD ops as
2330+ * the original request. The original request was stat + op(s),
2331+ * the new copyup request will be copyup + the same op(s).
28252332 */
2826− if (!obj_request_overlaps_parent(obj_request))
2827− return true;
2333+ obj_req->osd_req = rbd_osd_req_create(obj_req, num_osd_ops);
2334+ if (!obj_req->osd_req)
2335+ return -ENOMEM;
28282336
28292337 /*
2830− * Entire-object layered writes - we will overwrite whatever
2831− * parent data there is anyway.
2338+ * Only send non-zero copyup data to save some I/O and network
2339+ * bandwidth -- zero copyup data is equivalent to the object not
2340+ * existing.
28322341 */
2833− if (!obj_request->offset &&
2834− obj_request->length == rbd_obj_bytes(&rbd_dev->header))
2835− return true;
2342+ if (is_zero_bvecs(obj_req->copyup_bvecs, bytes)) {
2343+ dout("%s obj_req %p detected zeroes\n", __func__, obj_req);
2344+ bytes = 0;
2345+ }
28362346
2837− /*
2838− * If the object is known to already exist, its parent data has
2839− * already been copied.
2840− */
2841− if (obj_request_known_test(obj_request) &&
2842− obj_request_exists_test(obj_request))
2843− return true;
2347+ osd_req_op_cls_init(obj_req->osd_req, 0, CEPH_OSD_OP_CALL, "rbd",
2348+ "copyup");
2349+ osd_req_op_cls_request_data_bvecs(obj_req->osd_req, 0,
2350+ obj_req->copyup_bvecs, bytes);
2351+
2352+ switch (obj_req->img_request->op_type) {
2353+ case OBJ_OP_WRITE:
2354+ __rbd_obj_setup_write(obj_req, 1);
2355+ break;
2356+ case OBJ_OP_DISCARD:
2357+ rbd_assert(!rbd_obj_is_entire(obj_req));
2358+ __rbd_obj_setup_discard(obj_req, 1);
2359+ break;
2360+ default:
2361+ rbd_assert(0);
2362+ }
28442363
2845− return false;
2364+ rbd_obj_request_submit(obj_req);
2365+ return 0;
28462366 }
28472367
2848−static int rbd_img_obj_request_submit(struct rbd_obj_request *obj_request)
2368+static int setup_copyup_bvecs(struct rbd_obj_request *obj_req, u64 obj_overlap)
28492369 {
2850− rbd_assert(obj_request_img_data_test(obj_request));
2851− rbd_assert(obj_request_type_valid(obj_request->type));
2852− rbd_assert(obj_request->img_request);
2370+ u32 i;
28532371
2854− if (img_obj_request_simple(obj_request)) {
2855− rbd_obj_request_submit(obj_request);
2856− return 0;
2857− }
2372+ rbd_assert(!obj_req->copyup_bvecs);
2373+ obj_req->copyup_bvec_count = calc_pages_for(0, obj_overlap);
2374+ obj_req->copyup_bvecs = kcalloc(obj_req->copyup_bvec_count,
2375+ sizeof(*obj_req->copyup_bvecs),
2376+ GFP_NOIO);
2377+ if (!obj_req->copyup_bvecs)
2378+ return -ENOMEM;
28582379
2859− /*
2860− * It's a layered write. The target object might exist but
2861− * we may not know that yet. If we know it doesn't exist,
2862− * start by reading the data for the full target object from
2863− * the parent so we can use it for a copyup to the target.
2864− */
2865− if (obj_request_known_test(obj_request))
2866− return rbd_img_obj_parent_read_full(obj_request);
2380+ for (i = 0; i < obj_req->copyup_bvec_count; i++) {
2381+ unsigned int len = min(obj_overlap, (u64)PAGE_SIZE);
2382+
2383+ obj_req->copyup_bvecs[i].bv_page = alloc_page(GFP_NOIO);
2384+ if (!obj_req->copyup_bvecs[i].bv_page)
2385+ return -ENOMEM;
28672386
2868− /* We don't know whether the target exists. Go find out. */
2387+ obj_req->copyup_bvecs[i].bv_offset = 0;
2388+ obj_req->copyup_bvecs[i].bv_len = len;
2389+ obj_overlap -= len;
2390+ }
28692391
2870− return rbd_img_obj_exists_submit(obj_request);
2392+ rbd_assert(!obj_overlap);
2393+ return 0;
28712394 }
28722395
2873−static int rbd_img_request_submit(struct rbd_img_request *img_request)
2396+static int rbd_obj_handle_write_guard(struct rbd_obj_request *obj_req)
28742397 {
2875− struct rbd_obj_request *obj_request;
2876− struct rbd_obj_request *next_obj_request;
2877− int ret = 0;
2878−
2879− dout("%s: img %p\n", __func__, img_request);
2398+ struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev;
2399+ int ret;
28802400
2881− rbd_img_request_get(img_request);
2882− for_each_obj_request_safe(img_request, obj_request, next_obj_request) {
2883− ret = rbd_img_obj_request_submit(obj_request);
2884− if (ret)
2885− goto out_put_ireq;
2401+ rbd_assert(obj_req->num_img_extents);
2402+ prune_extents(obj_req->img_extents, &obj_req->num_img_extents,
2403+ rbd_dev->parent_overlap);
2404+ if (!obj_req->num_img_extents) {
2405+ /*
2406+ * The overlap has become 0 (most likely because the
2407+ * image has been flattened). Use rbd_obj_issue_copyup()
2408+ * to re-submit the original write request -- the copyup
2409+ * operation itself will be a no-op, since someone must
2410+ * have populated the child object while we weren't
2411+ * looking. Move to WRITE_FLAT state as we'll be done
2412+ * with the operation once the null copyup completes.
2413+ */
2414+ obj_req->write_state = RBD_OBJ_WRITE_FLAT;
2415+ return rbd_obj_issue_copyup(obj_req, 0);
28862416 }
28872417
2888−out_put_ireq:
2889− rbd_img_request_put(img_request);
2890− return ret;
2418+ ret = setup_copyup_bvecs(obj_req, rbd_obj_img_extents_bytes(obj_req));
2419+ if (ret)
2420+ return ret;
2421+
2422+ obj_req->write_state = RBD_OBJ_WRITE_COPYUP;
2423+ return rbd_obj_read_from_parent(obj_req);
28912424 }
28922425
2893−static void rbd_img_parent_read_callback(struct rbd_img_request *img_request)
2426+static bool rbd_obj_handle_write(struct rbd_obj_request *obj_req)
28942427 {
2895− struct rbd_obj_request *obj_request;
2896− struct rbd_device *rbd_dev;
2897− u64 obj_end;
2898− u64 img_xferred;
2899− int img_result;
2428+ int ret;
29002429
2901− rbd_assert(img_request_child_test(img_request));
2430+again:
2431+ switch (obj_req->write_state) {
2432+ case RBD_OBJ_WRITE_GUARD:
2433+ rbd_assert(!obj_req->xferred);
2434+ if (obj_req->result == -ENOENT) {
2435+ /*
2436+ * The target object doesn't exist. Read the data for
2437+ * the entire target object up to the overlap point (if
2438+ * any) from the parent, so we can use it for a copyup.
2439+ */
2440+ ret = rbd_obj_handle_write_guard(obj_req);
2441+ if (ret) {
2442+ obj_req->result = ret;
2443+ return true;
2444+ }
2445+ return false;
2446+ }
2447+ /* fall through */
2448+ case RBD_OBJ_WRITE_FLAT:
2449+ if (!obj_req->result)
2450+ /*
2451+ * There is no such thing as a successful short
2452+ * write -- indicate the whole request was satisfied.
2453+ */
2454+ obj_req->xferred = obj_req->ex.oe_len;
2455+ return true;
2456+ case RBD_OBJ_WRITE_COPYUP:
2457+ obj_req->write_state = RBD_OBJ_WRITE_GUARD;
2458+ if (obj_req->result)
2459+ goto again;
29022460
2903− /* First get what we need from the image request and release it */
2461+ rbd_assert(obj_req->xferred);
2462+ ret = rbd_obj_issue_copyup(obj_req, obj_req->xferred);
2463+ if (ret) {
2464+ obj_req->result = ret;
2465+ return true;
2466+ }
2467+ return false;
2468+ default:
2469+ rbd_assert(0);
2470+ }
2471+}
29042472
2905− obj_request = img_request->obj_request;
2906− img_xferred = img_request->xferred;
2907− img_result = img_request->result;
2908− rbd_img_request_put(img_request);
2473+/*
2474+ * Returns true if @obj_req is completed, or false otherwise.
2475+ */
2476+static bool __rbd_obj_handle_request(struct rbd_obj_request *obj_req)
2477+{
2478+ switch (obj_req->img_request->op_type) {
2479+ case OBJ_OP_READ:
2480+ return rbd_obj_handle_read(obj_req);
2481+ case OBJ_OP_WRITE:
2482+ return rbd_obj_handle_write(obj_req);
2483+ case OBJ_OP_DISCARD:
2484+ if (rbd_obj_handle_write(obj_req)) {
2485+ /*
2486+ * Hide -ENOENT from delete/truncate/zero -- discarding
2487+ * a non-existent object is not a problem.
2488+ */
2489+ if (obj_req->result == -ENOENT) {
2490+ obj_req->result = 0;
2491+ obj_req->xferred = obj_req->ex.oe_len;
2492+ }
2493+ return true;
2494+ }
2495+ return false;
2496+ default:
2497+ rbd_assert(0);
2498+ }
2499+}
29092500
2910− /*
2911− * If the overlap has become 0 (most likely because the
2912− * image has been flattened) we need to re-submit the
2913− * original request.
2914− */
2915− rbd_assert(obj_request);
2916− rbd_assert(obj_request->img_request);
2917− rbd_dev = obj_request->img_request->rbd_dev;
2918− if (!rbd_dev->parent_overlap) {
2919− rbd_obj_request_submit(obj_request);
2501+static void rbd_obj_end_request(struct rbd_obj_request *obj_req)
2502+{
2503+ struct rbd_img_request *img_req = obj_req->img_request;
2504+
2505+ rbd_assert((!obj_req->result &&
2506+ obj_req->xferred == obj_req->ex.oe_len) ||
2507+ (obj_req->result < 0 && !obj_req->xferred));
2508+ if (!obj_req->result) {
2509+ img_req->xferred += obj_req->xferred;
29202510 return;
29212511 }
29222512
2923− obj_request->result = img_result;
2924− if (obj_request->result)
2925− goto out;
2513+ rbd_warn(img_req->rbd_dev,
2514+ "%s at objno %llu %llu~%llu result %d xferred %llu",
2515+ obj_op_name(img_req->op_type), obj_req->ex.oe_objno,
2516+ obj_req->ex.oe_off, obj_req->ex.oe_len, obj_req->result,
2517+ obj_req->xferred);
2518+ if (!img_req->result) {
2519+ img_req->result = obj_req->result;
2520+ img_req->xferred = 0;
2521+ }
2522+}
29262523
2927− /*
2928− * We need to zero anything beyond the parent overlap
2929− * boundary. Since rbd_img_obj_request_read_callback()
2930− * will zero anything beyond the end of a short read, an
2931− * easy way to do this is to pretend the data from the
2932− * parent came up short--ending at the overlap boundary.
2933− */
2934− rbd_assert(obj_request->img_offset < U64_MAX - obj_request->length);
2935− obj_end = obj_request->img_offset + obj_request->length;
2936− if (obj_end > rbd_dev->parent_overlap) {
2937− u64 xferred = 0;
2524+static void rbd_img_end_child_request(struct rbd_img_request *img_req)
2525+{
2526+ struct rbd_obj_request *obj_req = img_req->obj_request;
29382527
2939− if (obj_request->img_offset < rbd_dev->parent_overlap)
2940− xferred = rbd_dev->parent_overlap -
2941− obj_request->img_offset;
2528+ rbd_assert(test_bit(IMG_REQ_CHILD, &img_req->flags));
2529+ rbd_assert((!img_req->result &&
2530+ img_req->xferred == rbd_obj_img_extents_bytes(obj_req)) ||
2531+ (img_req->result < 0 && !img_req->xferred));
29422532
2943− obj_request->xferred = min(img_xferred, xferred);
2944− } else {
2945− obj_request->xferred = img_xferred;
2946− }
2947−out:
2948− rbd_img_obj_request_read_callback(obj_request);
2949− rbd_obj_request_complete(obj_request);
2533+ obj_req->result = img_req->result;
2534+ obj_req->xferred = img_req->xferred;
2535+ rbd_img_request_put(img_req);
29502536 }
29512537
2952−static void rbd_img_parent_read(struct rbd_obj_request *obj_request)
2538+static void rbd_img_end_request(struct rbd_img_request *img_req)
29532539 {
2954− struct rbd_img_request *img_request;
2955− int result;
2540+ rbd_assert(!test_bit(IMG_REQ_CHILD, &img_req->flags));
2541+ rbd_assert((!img_req->result &&
2542+ img_req->xferred == blk_rq_bytes(img_req->rq)) ||
2543+ (img_req->result < 0 && !img_req->xferred));
29562544
2957− rbd_assert(obj_request_img_data_test(obj_request));
2958− rbd_assert(obj_request->img_request != NULL);
2959− rbd_assert(obj_request->result == (s32) -ENOENT);
2960− rbd_assert(obj_request_type_valid(obj_request->type));
2545+ blk_mq_end_request(img_req->rq,
2546+ errno_to_blk_status(img_req->result));
2547+ rbd_img_request_put(img_req);
2548+}
29612549
2962− /* rbd_read_finish(obj_request, obj_request->length); */
2963− img_request = rbd_parent_request_create(obj_request,
2964− obj_request->img_offset,
2965− obj_request->length);
2966− result = -ENOMEM;
2967− if (!img_request)
2968− goto out_err;
2550+static void rbd_obj_handle_request(struct rbd_obj_request *obj_req)
2551+{
2552+ struct rbd_img_request *img_req;
29692553
2970− if (obj_request->type == OBJ_REQUEST_BIO)
2971− result = rbd_img_request_fill(img_request, OBJ_REQUEST_BIO,
2972− obj_request->bio_list);
2973− else
2974− result = rbd_img_request_fill(img_request, OBJ_REQUEST_PAGES,
2975− obj_request->pages);
2976− if (result)
2977− goto out_err;
2554+again:
2555+ if (!__rbd_obj_handle_request(obj_req))
2556+ return;
29782557
2979− img_request->callback = rbd_img_parent_read_callback;
2980− result = rbd_img_request_submit(img_request);
2981− if (result)
2982− goto out_err;
2558+ img_req = obj_req->img_request;
2559+ spin_lock(&img_req->completion_lock);
2560+ rbd_obj_end_request(obj_req);
2561+ rbd_assert(img_req->pending_count);
2562+ if (--img_req->pending_count) {
2563+ spin_unlock(&img_req->completion_lock);
2564+ return;
2565+ }
29832566
2984− return;
2985−out_err:
2986− if (img_request)
2987− rbd_img_request_put(img_request);
2988− obj_request->result = result;
2989− obj_request->xferred = 0;
2990− obj_request_done_set(obj_request);
2567+ spin_unlock(&img_req->completion_lock);
2568+ if (test_bit(IMG_REQ_CHILD, &img_req->flags)) {
2569+ obj_req = img_req->obj_request;
2570+ rbd_img_end_child_request(img_req);
2571+ goto again;
2572+ }
2573+ rbd_img_end_request(img_req);
29912574 }
29922575
29932576 static const struct rbd_client_id rbd_empty_cid;
@@ -3091,8 +2674,8 @@ static int __rbd_notify_op_lock(struct rbd_device *rbd_dev, · 97 unmodified lines
30912674 {
30922675 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc;
30932676 struct rbd_client_id cid = rbd_get_cid(rbd_dev);
3094− int buf_size = 4 + 8 + 8 + CEPH_ENCODING_START_BLK_LEN;
3095− char buf[buf_size];
2677+ char buf[4 + 8 + 8 + CEPH_ENCODING_START_BLK_LEN];
2678+ int buf_size = sizeof(buf);
30962679 void *p = buf;
30972680
30982681 dout("%s rbd_dev %p notify_op %d\n", __func__, rbd_dev, notify_op);
@@ -3610,8 +3193,8 @@ static void __rbd_acknowledge_notify(struct rbd_device *rbd_dev, · 511 unmodified lines
36103193 u64 notify_id, u64 cookie, s32 *result)
36113194 {
36123195 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc;
3613− int buf_size = 4 + CEPH_ENCODING_START_BLK_LEN;
3614− char buf[buf_size];
3196+ char buf[4 + CEPH_ENCODING_START_BLK_LEN];
3197+ int buf_size = sizeof(buf);
36153198 int ret;
36163199
36173200 if (result) {
@@ -3887,7 +3470,7 @@ static void rbd_reregister_watch(struct work_struct *work) · 269 unmodified lines
38873470
38883471 ret = rbd_dev_refresh(rbd_dev);
38893472 if (ret)
3890− rbd_warn(rbd_dev, "reregisteration refresh failed: %d", ret);
3473+ rbd_warn(rbd_dev, "reregistration refresh failed: %d", ret);
38913474 }
38923475
38933476 /*
@@ -4070,8 +3653,7 @@ static void rbd_queue_workfn(struct work_struct *work) · 176 unmodified lines
40703653 }
40713654 }
40723655
4073− img_request = rbd_img_request_create(rbd_dev, offset, length, op_type,
4074− snapc);
3656+ img_request = rbd_img_request_create(rbd_dev, op_type, snapc);
40753657 if (!img_request) {
40763658 result = -ENOMEM;
40773659 goto err_unlock;
@@ -4080,18 +3662,14 @@ static void rbd_queue_workfn(struct work_struct *work) · 2 unmodified lines
40803662 snapc = NULL; /* img_request consumes a ref */
40813663
40823664 if (op_type == OBJ_OP_DISCARD)
4083− result = rbd_img_request_fill(img_request, OBJ_REQUEST_NODATA,
4084− NULL);
3665+ result = rbd_img_fill_nodata(img_request, offset, length);
40853666 else
4086− result = rbd_img_request_fill(img_request, OBJ_REQUEST_BIO,
4087− rq->bio);
4088− if (result)
4089− goto err_img_request;
4090−
4091− result = rbd_img_request_submit(img_request);
3667+ result = rbd_img_fill_from_bio(img_request, offset, length,
3668+ rq->bio);
40923669 if (result)
40933670 goto err_img_request;
40943671
3672+ rbd_img_request_submit(img_request);
40953673 if (must_be_locked)
40963674 up_read(&rbd_dev->lock_rwsem);
40973675 return;
@@ -4369,7 +3947,7 @@ static int rbd_init_disk(struct rbd_device *rbd_dev) · 271 unmodified lines
43693947 blk_queue_max_hw_sectors(q, segment_size / SECTOR_SIZE);
43703948 q->limits.max_sectors = queue_max_hw_sectors(q);
43713949 blk_queue_max_segments(q, USHRT_MAX);
4372− blk_queue_max_segment_size(q, segment_size);
3950+ blk_queue_max_segment_size(q, UINT_MAX);
43733951 blk_queue_io_min(q, segment_size);
43743952 blk_queue_io_opt(q, segment_size);
43753953
@@ -5057,9 +4635,6 @@ static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev) · 681 unmodified lines
50574635 } __attribute__ ((packed)) striping_info_buf = { 0 };
50584636 size_t size = sizeof (striping_info_buf);
50594637 void *p;
5060− u64 obj_size;
5061− u64 stripe_unit;
5062− u64 stripe_count;
50634638 int ret;
50644639
50654640 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid,
@@ -5071,31 +4646,9 @@ static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev) · 5 unmodified lines
50714646 if (ret < size)
50724647 return -ERANGE;
50734648
5074− /*
5075− * We don't actually support the "fancy striping" feature
5076− * (STRIPINGV2) yet, but if the striping sizes are the
5077− * defaults the behavior is the same as before. So find
5078− * out, and only fail if the image has non-default values.
5079− */
5080− ret = -EINVAL;
5081− obj_size = rbd_obj_bytes(&rbd_dev->header);
50824649 p = &striping_info_buf;
5083− stripe_unit = ceph_decode_64(&p);
5084− if (stripe_unit != obj_size) {
5085− rbd_warn(rbd_dev, "unsupported stripe unit "
5086− "(got %llu want %llu)",
5087− stripe_unit, obj_size);
5088− return -EINVAL;
5089− }
5090− stripe_count = ceph_decode_64(&p);
5091− if (stripe_count != 1) {
5092− rbd_warn(rbd_dev, "unsupported stripe count "
5093− "(got %llu want 1)", stripe_count);
5094− return -EINVAL;
5095− }
5096− rbd_dev->header.stripe_unit = stripe_unit;
5097− rbd_dev->header.stripe_count = stripe_count;
5098−
4650+ rbd_dev->header.stripe_unit = ceph_decode_64(&p);
4651+ rbd_dev->header.stripe_count = ceph_decode_64(&p);
50994652 return 0;
51004653 }
51014654
@@ -5653,39 +5206,6 @@ out_err: · 551 unmodified lines
56535206 return ret;
56545207 }
56555208
5656−/*
5657− * Return pool id (>= 0) or a negative error code.
5658− */
5659−static int rbd_add_get_pool_id(struct rbd_client *rbdc, const char *pool_name)
5660−{
5661− struct ceph_options *opts = rbdc->client->options;
5662− u64 newest_epoch;
5663− int tries = 0;
5664− int ret;
5665−
5666−again:
5667− ret = ceph_pg_poolid_by_name(rbdc->client->osdc.osdmap, pool_name);
5668− if (ret == -ENOENT && tries++ < 1) {
5669− ret = ceph_monc_get_version(&rbdc->client->monc, "osdmap",
5670− &newest_epoch);
5671− if (ret < 0)
5672− return ret;
5673−
5674− if (rbdc->client->osdc.osdmap->epoch < newest_epoch) {
5675− ceph_osdc_maybe_request_map(&rbdc->client->osdc);
5676− (void) ceph_monc_wait_osdmap(&rbdc->client->monc,
5677− newest_epoch,
5678− opts->mount_timeout);
5679− goto again;
5680− } else {
5681− /* the osdmap we have is new enough */
5682− return -ENOENT;
5683− }
5684− }
5685−
5686− return ret;
5687−}
5688−
56895209 static void rbd_dev_image_unlock(struct rbd_device *rbd_dev)
56905210 {
56915211 down_write(&rbd_dev->lock_rwsem);
@@ -6114,7 +5634,7 @@ static ssize_t do_rbd_add(struct bus_type *bus, · 422 unmodified lines
61145634 }
61155635
61165636 /* pick the pool */
6117− rc = rbd_add_get_pool_id(rbdc, spec->pool_name);
5637+ rc = ceph_pg_poolid_by_name(rbdc->client->osdc.osdmap, spec->pool_name);
61185638 if (rc < 0) {
61195639 if (rc == -ENOENT)
61205640 pr_info("pool %s does not exist\n", spec->pool_name);
@@ -6366,16 +5886,8 @@ static int rbd_slab_init(void) · 245 unmodified lines
63665886 if (!rbd_obj_request_cache)
63675887 goto out_err;
63685888
6369− rbd_assert(!rbd_bio_clone);
6370− rbd_bio_clone = bioset_create(BIO_POOL_SIZE, 0, 0);
6371− if (!rbd_bio_clone)
6372− goto out_err_clone;
6373−
63745889 return 0;
63755890
6376−out_err_clone:
6377− kmem_cache_destroy(rbd_obj_request_cache);
6378− rbd_obj_request_cache = NULL;
63795891 out_err:
63805892 kmem_cache_destroy(rbd_img_request_cache);
63815893 rbd_img_request_cache = NULL;
@@ -6391,10 +5903,6 @@ static void rbd_slab_exit(void) · 9 unmodified lines
63915903 rbd_assert(rbd_img_request_cache);
63925904 kmem_cache_destroy(rbd_img_request_cache);
63935905 rbd_img_request_cache = NULL;
6394−
6395− rbd_assert(rbd_bio_clone);
6396− bioset_free(rbd_bio_clone);
6397− rbd_bio_clone = NULL;
63985906 }
63995907
64005908 static int __init rbd_init(void)
fs/ceph/Makefile+1−1
@@ -6,7 +6,7 @@ · 5 unmodified lines
66 obj-$(CONFIG_CEPH_FS) += ceph.o
77
88 ceph-y := super.o inode.o dir.o file.o locks.o addr.o ioctl.o \
9− export.o caps.o snap.o xattr.o \
9+ export.o caps.o snap.o xattr.o quota.o \
1010 mds_client.o mdsmap.o strings.o ceph_frag.o \
1111 debugfs.o
1212
fs/ceph/addr.c+32−31
@@ -15,6 +15,7 @@ · 14 unmodified lines
1515 #include "mds_client.h"
1616 #include "cache.h"
1717 #include <linux/ceph/osd_client.h>
18+#include <linux/ceph/striper.h>
1819
1920 /*
2021 * Ceph address space ops.
@@ -438,7 +439,7 @@ static int ceph_readpages(struct file *file, struct address_space *mapping, · 417 unmodified lines
438439 {
439440 struct inode *inode = file_inode(file);
440441 struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
441− struct ceph_file_info *ci = file->private_data;
442+ struct ceph_file_info *fi = file->private_data;
442443 struct ceph_rw_context *rw_ctx;
443444 int rc = 0;
444445 int max = 0;
@@ -452,7 +453,7 @@ static int ceph_readpages(struct file *file, struct address_space *mapping, · 7 unmodified lines
452453 if (rc == 0)
453454 goto out;
454455
455− rw_ctx = ceph_find_rw_context(ci);
456+ rw_ctx = ceph_find_rw_context(fi);
456457 max = fsc->mount_options->rsize >> PAGE_SHIFT;
457458 dout("readpages %p file %p ctx %p nr_pages %d max %d\n",
458459 inode, file, rw_ctx, nr_pages, max);
@@ -800,7 +801,7 @@ static int ceph_writepages_start(struct address_space *mapping, · 341 unmodified lines
800801 struct ceph_osd_request *req = NULL;
801802 struct ceph_writeback_ctl ceph_wbc;
802803 bool should_loop, range_whole = false;
803− bool stop, done = false;
804+ bool done = false;
804805
805806 dout("writepages_start %p (mode=%s)\n", inode,
806807 wbc->sync_mode == WB_SYNC_NONE ? "NONE" :
@@ -856,7 +857,7 @@ retry: · 49 unmodified lines
856857 * in that range can be associated with newer snapc.
857858 * They are not writeable until we write all dirty pages
858859 * associated with 'snapc' get written */
859− if (index > 0 || wbc->sync_mode != WB_SYNC_NONE)
860+ if (index > 0)
860861 should_loop = true;
861862 dout(" non-head snapc, range whole\n");
862863 }
@@ -864,8 +865,7 @@ retry: · 1 unmodified line
864865 ceph_put_snap_context(last_snapc);
865866 last_snapc = snapc;
866867
867− stop = false;
868− while (!stop && index <= end) {
868+ while (!done && index <= end) {
869869 int num_ops = 0, op_idx;
870870 unsigned i, pvec_pages, max_pages, locked_pages = 0;
871871 struct page **pages = NULL, **data_pages;
@@ -898,16 +898,30 @@ get_more_pages: · 26 unmodified lines
898898 unlock_page(page);
899899 continue;
900900 }
901− if (strip_unit_end && (page->index > strip_unit_end)) {
902− dout("end of strip unit %p\n", page);
901+ /* only if matching snap context */
902+ pgsnapc = page_snap_context(page);
903+ if (pgsnapc != snapc) {
904+ dout("page snapc %p %lld != oldest %p %lld\n",
905+ pgsnapc, pgsnapc->seq, snapc, snapc->seq);
906+ if (!should_loop &&
907+ !ceph_wbc.head_snapc &&
908+ wbc->sync_mode != WB_SYNC_NONE)
909+ should_loop = true;
903910 unlock_page(page);
904− break;
911+ continue;
905912 }
906913 if (page_offset(page) >= ceph_wbc.i_size) {
907914 dout("%p page eof %llu\n",
908915 page, ceph_wbc.i_size);
909− /* not done if range_cyclic */
910− stop = true;
916+ if (ceph_wbc.size_stable ||
917+ page_offset(page) >= i_size_read(inode))
918+ mapping->a_ops->invalidatepage(page,
919+ 0, PAGE_SIZE);
920+ unlock_page(page);
921+ continue;
922+ }
923+ if (strip_unit_end && (page->index > strip_unit_end)) {
924+ dout("end of strip unit %p\n", page);
911925 unlock_page(page);
912926 break;
913927 }
@@ -921,15 +935,6 @@ get_more_pages: · 7 unmodified lines
921935 wait_on_page_writeback(page);
922936 }
923937
924− /* only if matching snap context */
925− pgsnapc = page_snap_context(page);
926− if (pgsnapc != snapc) {
927− dout("page snapc %p %lld != oldest %p %lld\n",
928− pgsnapc, pgsnapc->seq, snapc, snapc->seq);
929− unlock_page(page);
930− continue;
931− }
932−
933938 if (!clear_page_dirty_for_io(page)) {
934939 dout("%p !clear_page_dirty_for_io\n", page);
935940 unlock_page(page);
@@ -945,19 +950,15 @@ get_more_pages: · 9 unmodified lines
945950 if (locked_pages == 0) {
946951 u64 objnum;
947952 u64 objoff;
953+ u32 xlen;
948954
949955 /* prepare async write request */
950956 offset = (u64)page_offset(page);
951− len = wsize;
952−
953− rc = ceph_calc_file_object_mapping(&ci->i_layout,
954− offset, len,
955− &objnum, &objoff,
956− &len);
957− if (rc < 0) {
958− unlock_page(page);
959− break;
960− }
957+ ceph_calc_file_object_mapping(&ci->i_layout,
958+ offset, wsize,
959+ &objnum, &objoff,
960+ &xlen);
961+ len = xlen;
961962
962963 num_ops = 1;
963964 strip_unit_end = page->index +
@@ -1146,7 +1147,7 @@ new_request: · 182 unmodified lines
11461147 * we tagged for writeback prior to entering this loop.
11471148 */
11481149 if (wbc->nr_to_write <= 0 && wbc->sync_mode == WB_SYNC_NONE)
1149− done = stop = true;
1150+ done = true;
11501151
11511152 release_pvec_pages:
11521153 dout("pagevec_release on %d pages (%p)\n", (int)pvec.nr,
fs/ceph/cache.c+2−2
@@ -51,7 +51,7 @@ static const struct fscache_cookie_def ceph_fscache_fsid_object_def = { · 50 unmodified lines
5151 .type = FSCACHE_COOKIE_TYPE_INDEX,
5252 };
5353
54−int ceph_fscache_register(void)
54+int __init ceph_fscache_register(void)
5555 {
5656 return fscache_register_netfs(&ceph_cache_netfs);
5757 }
@@ -135,7 +135,7 @@ static enum fscache_checkaux ceph_fscache_inode_check_aux( · 77 unmodified lines
135135 if (memcmp(data, &aux, sizeof(aux)) != 0)
136136 return FSCACHE_CHECKAUX_OBSOLETE;
137137
138− dout("ceph inode 0x%p cached okay", ci);
138+ dout("ceph inode 0x%p cached okay\n", ci);
139139 return FSCACHE_CHECKAUX_OKAY;
140140 }
141141
fs/ceph/caps.c+97−31
@@ -184,36 +184,54 @@ int ceph_reserve_caps(struct ceph_mds_client *mdsc, · 183 unmodified lines
184184 mdsc->caps_avail_count);
185185 spin_unlock(&mdsc->caps_list_lock);
186186
187− for (i = have; i < need; i++) {
188−retry:
187+ for (i = have; i < need; ) {
189188 cap = kmem_cache_alloc(ceph_cap_cachep, GFP_NOFS);
190− if (!cap) {
191− if (!trimmed) {
192− for (j = 0; j < mdsc->max_sessions; j++) {
193− s = __ceph_lookup_mds_session(mdsc, j);
194− if (!s)
195− continue;
196− mutex_unlock(&mdsc->mutex);
189+ if (cap) {
190+ list_add(&cap->caps_item, &newcaps);
191+ alloc++;
192+ i++;
193+ continue;
194+ }
197195
198− mutex_lock(&s->s_mutex);
199− max_caps = s->s_nr_caps - (need - i);
200− ceph_trim_caps(mdsc, s, max_caps);
201− mutex_unlock(&s->s_mutex);
196+ if (!trimmed) {
197+ for (j = 0; j < mdsc->max_sessions; j++) {
198+ s = __ceph_lookup_mds_session(mdsc, j);
199+ if (!s)
200+ continue;
201+ mutex_unlock(&mdsc->mutex);
202202
203− ceph_put_mds_session(s);
204− mutex_lock(&mdsc->mutex);
205− }
206− trimmed = true;
207− goto retry;
208− } else {
209− pr_warn("reserve caps ctx=%p ENOMEM "
210− "need=%d got=%d\n",
211− ctx, need, have + alloc);
212− goto out_nomem;
203+ mutex_lock(&s->s_mutex);
204+ max_caps = s->s_nr_caps - (need - i);
205+ ceph_trim_caps(mdsc, s, max_caps);
206+ mutex_unlock(&s->s_mutex);
207+
208+ ceph_put_mds_session(s);
209+ mutex_lock(&mdsc->mutex);
213210 }
211+ trimmed = true;
212+
213+ spin_lock(&mdsc->caps_list_lock);
214+ if (mdsc->caps_avail_count) {
215+ int more_have;
216+ if (mdsc->caps_avail_count >= need - i)
217+ more_have = need - i;
218+ else
219+ more_have = mdsc->caps_avail_count;
220+
221+ i += more_have;
222+ have += more_have;
223+ mdsc->caps_avail_count -= more_have;
224+ mdsc->caps_reserve_count += more_have;
225+
226+ }
227+ spin_unlock(&mdsc->caps_list_lock);
228+
229+ continue;
214230 }
215− list_add(&cap->caps_item, &newcaps);
216− alloc++;
231+
232+ pr_warn("reserve caps ctx=%p ENOMEM need=%d got=%d\n",
233+ ctx, need, have + alloc);
234+ goto out_nomem;
217235 }
218236 BUG_ON(have + alloc != need);
219237
@@ -234,16 +252,28 @@ retry: · 14 unmodified lines
234252 return 0;
235253
236254 out_nomem:
255+
256+ spin_lock(&mdsc->caps_list_lock);
257+ mdsc->caps_avail_count += have;
258+ mdsc->caps_reserve_count -= have;
259+
237260 while (!list_empty(&newcaps)) {
238261 cap = list_first_entry(&newcaps,
239262 struct ceph_cap, caps_item);
240263 list_del(&cap->caps_item);
241− kmem_cache_free(ceph_cap_cachep, cap);
264+
265+ /* Keep some preallocated caps around (ceph_min_count), to
266+ * avoid lots of free/alloc churn. */
267+ if (mdsc->caps_avail_count >=
268+ mdsc->caps_reserve_count + mdsc->caps_min_count) {
269+ kmem_cache_free(ceph_cap_cachep, cap);
270+ } else {
271+ mdsc->caps_avail_count++;
272+ mdsc->caps_total_count++;
273+ list_add(&cap->caps_item, &mdsc->caps_list);
274+ }
242275 }
243276
244− spin_lock(&mdsc->caps_list_lock);
245− mdsc->caps_avail_count += have;
246− mdsc->caps_reserve_count -= have;
247277 BUG_ON(mdsc->caps_total_count != mdsc->caps_use_count +
248278 mdsc->caps_reserve_count +
249279 mdsc->caps_avail_count);
@@ -254,12 +284,26 @@ out_nomem: · 4 unmodified lines
254284 int ceph_unreserve_caps(struct ceph_mds_client *mdsc,
255285 struct ceph_cap_reservation *ctx)
256286 {
287+ int i;
288+ struct ceph_cap *cap;
289+
257290 dout("unreserve caps ctx=%p count=%d\n", ctx, ctx->count);
258291 if (ctx->count) {
259292 spin_lock(&mdsc->caps_list_lock);
260293 BUG_ON(mdsc->caps_reserve_count < ctx->count);
261294 mdsc->caps_reserve_count -= ctx->count;
262− mdsc->caps_avail_count += ctx->count;
295+ if (mdsc->caps_avail_count >=
296+ mdsc->caps_reserve_count + mdsc->caps_min_count) {
297+ mdsc->caps_total_count -= ctx->count;
298+ for (i = 0; i < ctx->count; i++) {
299+ cap = list_first_entry(&mdsc->caps_list,
300+ struct ceph_cap, caps_item);
301+ list_del(&cap->caps_item);
302+ kmem_cache_free(ceph_cap_cachep, cap);
303+ }
304+ } else {
305+ mdsc->caps_avail_count += ctx->count;
306+ }
263307 ctx->count = 0;
264308 dout("unreserve caps %d = %d used + %d resv + %d avail\n",
265309 mdsc->caps_total_count, mdsc->caps_use_count,
@@ -285,7 +329,23 @@ struct ceph_cap *ceph_get_cap(struct ceph_mds_client *mdsc, · 19 unmodified lines
285329 mdsc->caps_use_count++;
286330 mdsc->caps_total_count++;
287331 spin_unlock(&mdsc->caps_list_lock);
332+ } else {
333+ spin_lock(&mdsc->caps_list_lock);
334+ if (mdsc->caps_avail_count) {
335+ BUG_ON(list_empty(&mdsc->caps_list));
336+
337+ mdsc->caps_avail_count--;
338+ mdsc->caps_use_count++;
339+ cap = list_first_entry(&mdsc->caps_list,
340+ struct ceph_cap, caps_item);
341+ list_del(&cap->caps_item);
342+
343+ BUG_ON(mdsc->caps_total_count != mdsc->caps_use_count +
344+ mdsc->caps_reserve_count + mdsc->caps_avail_count);
345+ }
346+ spin_unlock(&mdsc->caps_list_lock);
288347 }
348+
289349 return cap;
290350 }
291351
@@ -341,6 +401,8 @@ void ceph_reservation_status(struct ceph_fs_client *fsc, · 49 unmodified lines
341401 {
342402 struct ceph_mds_client *mdsc = fsc->mdsc;
343403
404+ spin_lock(&mdsc->caps_list_lock);
405+
344406 if (total)
345407 *total = mdsc->caps_total_count;
346408 if (avail)
@@ -351,6 +413,8 @@ void ceph_reservation_status(struct ceph_fs_client *fsc, · 4 unmodified lines
351413 *reserved = mdsc->caps_reserve_count;
352414 if (min)
353415 *min = mdsc->caps_min_count;
416+
417+ spin_unlock(&mdsc->caps_list_lock);
354418 }
355419
356420 /*
@@ -639,9 +703,11 @@ void ceph_add_cap(struct inode *inode, · 282 unmodified lines
639703 }
640704
641705 spin_lock(&realm->inodes_with_caps_lock);
642− ci->i_snap_realm = realm;
643706 list_add(&ci->i_snap_realm_item,
644707 &realm->inodes_with_caps);
708+ ci->i_snap_realm = realm;
709+ if (realm->ino == ci->i_vino.ino)
710+ realm->inode = inode;
645711 spin_unlock(&realm->inodes_with_caps_lock);
646712
647713 if (oldrealm)
fs/ceph/debugfs.c+4−4
@@ -260,7 +260,7 @@ int ceph_fs_debugfs_init(struct ceph_fs_client *fsc) · 259 unmodified lines
260260 goto out;
261261
262262 fsc->debugfs_mdsmap = debugfs_create_file("mdsmap",
263− 0600,
263+ 0400,
264264 fsc->client->debugfs_dir,
265265 fsc,
266266 &mdsmap_show_fops);
@@ -268,7 +268,7 @@ int ceph_fs_debugfs_init(struct ceph_fs_client *fsc) · 1 unmodified line
268268 goto out;
269269
270270 fsc->debugfs_mds_sessions = debugfs_create_file("mds_sessions",
271− 0600,
271+ 0400,
272272 fsc->client->debugfs_dir,
273273 fsc,
274274 &mds_sessions_show_fops);
@@ -276,7 +276,7 @@ int ceph_fs_debugfs_init(struct ceph_fs_client *fsc) · 1 unmodified line
276276 goto out;
277277
278278 fsc->debugfs_mdsc = debugfs_create_file("mdsc",
279− 0600,
279+ 0400,
280280 fsc->client->debugfs_dir,
281281 fsc,
282282 &mdsc_show_fops);
@@ -292,7 +292,7 @@ int ceph_fs_debugfs_init(struct ceph_fs_client *fsc) · 9 unmodified lines
292292 goto out;
293293
294294 fsc->debugfs_dentry_lru = debugfs_create_file("dentry_lru",
295− 0600,
295+ 0400,
296296 fsc->client->debugfs_dir,
297297 fsc,
298298 &dentry_lru_show_fops);
fs/ceph/dir.c+112−92
@@ -101,18 +101,18 @@ static int fpos_cmp(loff_t l, loff_t r) · 100 unmodified lines
101101 * regardless of what dir changes take place on the
102102 * server.
103103 */
104−static int note_last_dentry(struct ceph_file_info *fi, const char *name,
104+static int note_last_dentry(struct ceph_dir_file_info *dfi, const char *name,
105105 int len, unsigned next_offset)
106106 {
107107 char *buf = kmalloc(len+1, GFP_KERNEL);
108108 if (!buf)
109109 return -ENOMEM;
110− kfree(fi->last_name);
111− fi->last_name = buf;
112− memcpy(fi->last_name, name, len);
113− fi->last_name[len] = 0;
114− fi->next_offset = next_offset;
115− dout("note_last_dentry '%s'\n", fi->last_name);
110+ kfree(dfi->last_name);
111+ dfi->last_name = buf;
112+ memcpy(dfi->last_name, name, len);
113+ dfi->last_name[len] = 0;
114+ dfi->next_offset = next_offset;
115+ dout("note_last_dentry '%s'\n", dfi->last_name);
116116 return 0;
117117 }
118118
@@ -174,7 +174,7 @@ __dcache_find_get_entry(struct dentry *parent, u64 idx, · 55 unmodified lines
174174 static int __dcache_readdir(struct file *file, struct dir_context *ctx,
175175 int shared_gen)
176176 {
177− struct ceph_file_info *fi = file->private_data;
177+ struct ceph_dir_file_info *dfi = file->private_data;
178178 struct dentry *parent = file->f_path.dentry;
179179 struct inode *dir = d_inode(parent);
180180 struct dentry *dentry, *last = NULL;
@@ -221,7 +221,7 @@ static int __dcache_readdir(struct file *file, struct dir_context *ctx, · 40 unmodified lines
221221 bool emit_dentry = false;
222222 dentry = __dcache_find_get_entry(parent, idx++, &cache_ctl);
223223 if (!dentry) {
224− fi->flags |= CEPH_F_ATEND;
224+ dfi->file_info.flags |= CEPH_F_ATEND;
225225 err = 0;
226226 break;
227227 }
@@ -272,33 +272,33 @@ out: · 44 unmodified lines
272272 if (last) {
273273 int ret;
274274 di = ceph_dentry(last);
275− ret = note_last_dentry(fi, last->d_name.name, last->d_name.len,
275+ ret = note_last_dentry(dfi, last->d_name.name, last->d_name.len,
276276 fpos_off(di->offset) + 1);
277277 if (ret < 0)
278278 err = ret;
279279 dput(last);
280280 /* last_name no longer match cache index */
281− if (fi->readdir_cache_idx >= 0) {
282− fi->readdir_cache_idx = -1;
283− fi->dir_release_count = 0;
281+ if (dfi->readdir_cache_idx >= 0) {
282+ dfi->readdir_cache_idx = -1;
283+ dfi->dir_release_count = 0;
284284 }
285285 }
286286 return err;
287287 }
288288
289−static bool need_send_readdir(struct ceph_file_info *fi, loff_t pos)
289+static bool need_send_readdir(struct ceph_dir_file_info *dfi, loff_t pos)
290290 {
291− if (!fi->last_readdir)
291+ if (!dfi->last_readdir)
292292 return true;
293293 if (is_hash_order(pos))
294− return !ceph_frag_contains_value(fi->frag, fpos_hash(pos));
294+ return !ceph_frag_contains_value(dfi->frag, fpos_hash(pos));
295295 else
296− return fi->frag != fpos_frag(pos);
296+ return dfi->frag != fpos_frag(pos);
297297 }
298298
299299 static int ceph_readdir(struct file *file, struct dir_context *ctx)
300300 {
301− struct ceph_file_info *fi = file->private_data;
301+ struct ceph_dir_file_info *dfi = file->private_data;
302302 struct inode *inode = file_inode(file);
303303 struct ceph_inode_info *ci = ceph_inode(inode);
304304 struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
@@ -309,7 +309,7 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx) · 4 unmodified lines
309309 struct ceph_mds_reply_info_parsed *rinfo;
310310
311311 dout("readdir %p file %p pos %llx\n", inode, file, ctx->pos);
312− if (fi->flags & CEPH_F_ATEND)
312+ if (dfi->file_info.flags & CEPH_F_ATEND)
313313 return 0;
314314
315315 /* always start with . and .. */
@@ -350,15 +350,15 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx) · 34 unmodified lines
350350 /* proceed with a normal readdir */
351351 more:
352352 /* do we have the correct frag content buffered? */
353− if (need_send_readdir(fi, ctx->pos)) {
353+ if (need_send_readdir(dfi, ctx->pos)) {
354354 struct ceph_mds_request *req;
355355 int op = ceph_snap(inode) == CEPH_SNAPDIR ?
356356 CEPH_MDS_OP_LSSNAP : CEPH_MDS_OP_READDIR;
357357
358358 /* discard old result, if any */
359− if (fi->last_readdir) {
360− ceph_mdsc_put_request(fi->last_readdir);
361− fi->last_readdir = NULL;
359+ if (dfi->last_readdir) {
360+ ceph_mdsc_put_request(dfi->last_readdir);
361+ dfi->last_readdir = NULL;
362362 }
363363
364364 if (is_hash_order(ctx->pos)) {
@@ -372,7 +372,7 @@ more: · 7 unmodified lines
372372 }
373373
374374 dout("readdir fetching %llx.%llx frag %x offset '%s'\n",
375− ceph_vinop(inode), frag, fi->last_name);
375+ ceph_vinop(inode), frag, dfi->last_name);
376376 req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS);
377377 if (IS_ERR(req))
378378 return PTR_ERR(req);
@@ -388,8 +388,8 @@ more: · 9 unmodified lines
388388 __set_bit(CEPH_MDS_R_DIRECT_IS_HASH, &req->r_req_flags);
389389 req->r_inode_drop = CEPH_CAP_FILE_EXCL;
390390 }
391− if (fi->last_name) {
392− req->r_path2 = kstrdup(fi->last_name, GFP_KERNEL);
391+ if (dfi->last_name) {
392+ req->r_path2 = kstrdup(dfi->last_name, GFP_KERNEL);
393393 if (!req->r_path2) {
394394 ceph_mdsc_put_request(req);
395395 return -ENOMEM;
@@ -399,10 +399,10 @@ more: · 3 unmodified lines
399399 cpu_to_le32(fpos_hash(ctx->pos));
400400 }
401401
402− req->r_dir_release_cnt = fi->dir_release_count;
403− req->r_dir_ordered_cnt = fi->dir_ordered_count;
404− req->r_readdir_cache_idx = fi->readdir_cache_idx;
405− req->r_readdir_offset = fi->next_offset;
402+ req->r_dir_release_cnt = dfi->dir_release_count;
403+ req->r_dir_ordered_cnt = dfi->dir_ordered_count;
404+ req->r_readdir_cache_idx = dfi->readdir_cache_idx;
405+ req->r_readdir_offset = dfi->next_offset;
406406 req->r_args.readdir.frag = cpu_to_le32(frag);
407407 req->r_args.readdir.flags =
408408 cpu_to_le16(CEPH_READDIR_REPLY_BITFLAGS);
@@ -426,35 +426,35 @@ more: · 17 unmodified lines
426426 if (le32_to_cpu(rinfo->dir_dir->frag) != frag) {
427427 frag = le32_to_cpu(rinfo->dir_dir->frag);
428428 if (!rinfo->hash_order) {
429− fi->next_offset = req->r_readdir_offset;
429+ dfi->next_offset = req->r_readdir_offset;
430430 /* adjust ctx->pos to beginning of frag */
431431 ctx->pos = ceph_make_fpos(frag,
432− fi->next_offset,
432+ dfi->next_offset,
433433 false);
434434 }
435435 }
436436
437− fi->frag = frag;
438− fi->last_readdir = req;
437+ dfi->frag = frag;
438+ dfi->last_readdir = req;
439439
440440 if (test_bit(CEPH_MDS_R_DID_PREPOPULATE, &req->r_req_flags)) {
441− fi->readdir_cache_idx = req->r_readdir_cache_idx;
442− if (fi->readdir_cache_idx < 0) {
441+ dfi->readdir_cache_idx = req->r_readdir_cache_idx;
442+ if (dfi->readdir_cache_idx < 0) {
443443 /* preclude from marking dir ordered */
444− fi->dir_ordered_count = 0;
444+ dfi->dir_ordered_count = 0;
445445 } else if (ceph_frag_is_leftmost(frag) &&
446− fi->next_offset == 2) {
446+ dfi->next_offset == 2) {
447447 /* note dir version at start of readdir so
448448 * we can tell if any dentries get dropped */
449− fi->dir_release_count = req->r_dir_release_cnt;
450− fi->dir_ordered_count = req->r_dir_ordered_cnt;
449+ dfi->dir_release_count = req->r_dir_release_cnt;
450+ dfi->dir_ordered_count = req->r_dir_ordered_cnt;
451451 }
452452 } else {
453− dout("readdir !did_prepopulate");
453+ dout("readdir !did_prepopulate\n");
454454 /* disable readdir cache */
455− fi->readdir_cache_idx = -1;
455+ dfi->readdir_cache_idx = -1;
456456 /* preclude from marking dir complete */
457− fi->dir_release_count = 0;
457+ dfi->dir_release_count = 0;
458458 }
459459
460460 /* note next offset and last dentry name */
@@ -463,19 +463,19 @@ more: · 2 unmodified lines
463463 rinfo->dir_entries + (rinfo->dir_nr-1);
464464 unsigned next_offset = req->r_reply_info.dir_end ?
465465 2 : (fpos_off(rde->offset) + 1);
466− err = note_last_dentry(fi, rde->name, rde->name_len,
466+ err = note_last_dentry(dfi, rde->name, rde->name_len,
467467 next_offset);
468468 if (err)
469469 return err;
470470 } else if (req->r_reply_info.dir_end) {
471− fi->next_offset = 2;
471+ dfi->next_offset = 2;
472472 /* keep last name */
473473 }
474474 }
475475
476− rinfo = &fi->last_readdir->r_reply_info;
476+ rinfo = &dfi->last_readdir->r_reply_info;
477477 dout("readdir frag %x num %d pos %llx chunk first %llx\n",
478− fi->frag, rinfo->dir_nr, ctx->pos,
478+ dfi->frag, rinfo->dir_nr, ctx->pos,
479479 rinfo->dir_nr ? rinfo->dir_entries[0].offset : 0LL);
480480
481481 i = 0;
@@ -519,52 +519,55 @@ more: · 37 unmodified lines
519519 ctx->pos++;
520520 }
521521
522− ceph_mdsc_put_request(fi->last_readdir);
523− fi->last_readdir = NULL;
522+ ceph_mdsc_put_request(dfi->last_readdir);
523+ dfi->last_readdir = NULL;
524524
525− if (fi->next_offset > 2) {
526− frag = fi->frag;
525+ if (dfi->next_offset > 2) {
526+ frag = dfi->frag;
527527 goto more;
528528 }
529529
530530 /* more frags? */
531− if (!ceph_frag_is_rightmost(fi->frag)) {
532− frag = ceph_frag_next(fi->frag);
531+ if (!ceph_frag_is_rightmost(dfi->frag)) {
532+ frag = ceph_frag_next(dfi->frag);
533533 if (is_hash_order(ctx->pos)) {
534534 loff_t new_pos = ceph_make_fpos(ceph_frag_value(frag),
535− fi->next_offset, true);
535+ dfi->next_offset, true);
536536 if (new_pos > ctx->pos)
537537 ctx->pos = new_pos;
538538 /* keep last_name */
539539 } else {
540− ctx->pos = ceph_make_fpos(frag, fi->next_offset, false);
541− kfree(fi->last_name);
542− fi->last_name = NULL;
540+ ctx->pos = ceph_make_fpos(frag, dfi->next_offset,
541+ false);
542+ kfree(dfi->last_name);
543+ dfi->last_name = NULL;
543544 }
544545 dout("readdir next frag is %x\n", frag);
545546 goto more;
546547 }
547− fi->flags |= CEPH_F_ATEND;
548+ dfi->file_info.flags |= CEPH_F_ATEND;
548549
549550 /*
550551 * if dir_release_count still matches the dir, no dentries
551552 * were released during the whole readdir, and we should have
552553 * the complete dir contents in our cache.
553554 */
554− if (atomic64_read(&ci->i_release_count) == fi->dir_release_count) {
555+ if (atomic64_read(&ci->i_release_count) ==
556+ dfi->dir_release_count) {
555557 spin_lock(&ci->i_ceph_lock);
556− if (fi->dir_ordered_count == atomic64_read(&ci->i_ordered_count)) {
558+ if (dfi->dir_ordered_count ==
559+ atomic64_read(&ci->i_ordered_count)) {
557560 dout(" marking %p complete and ordered\n", inode);
558561 /* use i_size to track number of entries in
559562 * readdir cache */
560− BUG_ON(fi->readdir_cache_idx < 0);
561− i_size_write(inode, fi->readdir_cache_idx *
563+ BUG_ON(dfi->readdir_cache_idx < 0);
564+ i_size_write(inode, dfi->readdir_cache_idx *
562565 sizeof(struct dentry*));
563566 } else {
564567 dout(" marking %p complete\n", inode);
565568 }
566− __ceph_dir_set_complete(ci, fi->dir_release_count,
567− fi->dir_ordered_count);
569+ __ceph_dir_set_complete(ci, dfi->dir_release_count,
570+ dfi->dir_ordered_count);
568571 spin_unlock(&ci->i_ceph_lock);
569572 }
570573
@@ -572,25 +575,25 @@ more: · 1 unmodified line
572575 return 0;
573576 }
574577
575−static void reset_readdir(struct ceph_file_info *fi)
578+static void reset_readdir(struct ceph_dir_file_info *dfi)
576579 {
577− if (fi->last_readdir) {
578− ceph_mdsc_put_request(fi->last_readdir);
579− fi->last_readdir = NULL;
580+ if (dfi->last_readdir) {
581+ ceph_mdsc_put_request(dfi->last_readdir);
582+ dfi->last_readdir = NULL;
580583 }
581− kfree(fi->last_name);
582− fi->last_name = NULL;
583− fi->dir_release_count = 0;
584− fi->readdir_cache_idx = -1;
585− fi->next_offset = 2; /* compensate for . and .. */
586− fi->flags &= ~CEPH_F_ATEND;
584+ kfree(dfi->last_name);
585+ dfi->last_name = NULL;
586+ dfi->dir_release_count = 0;
587+ dfi->readdir_cache_idx = -1;
588+ dfi->next_offset = 2; /* compensate for . and .. */
589+ dfi->file_info.flags &= ~CEPH_F_ATEND;
587590 }
588591
589592 /*
590593 * discard buffered readdir content on seekdir(0), or seek to new frag,
591594 * or seek prior to current chunk
592595 */
593−static bool need_reset_readdir(struct ceph_file_info *fi, loff_t new_pos)
596+static bool need_reset_readdir(struct ceph_dir_file_info *dfi, loff_t new_pos)
594597 {
595598 struct ceph_mds_reply_info_parsed *rinfo;
596599 loff_t chunk_offset;
@@ -599,10 +602,10 @@ static bool need_reset_readdir(struct ceph_file_info *fi, loff_t new_pos) · 2 unmodified lines
599602 if (is_hash_order(new_pos)) {
600603 /* no need to reset last_name for a forward seek when
601604 * dentries are sotred in hash order */
602− } else if (fi->frag != fpos_frag(new_pos)) {
605+ } else if (dfi->frag != fpos_frag(new_pos)) {
603606 return true;
604607 }
605− rinfo = fi->last_readdir ? &fi->last_readdir->r_reply_info : NULL;
608+ rinfo = dfi->last_readdir ? &dfi->last_readdir->r_reply_info : NULL;
606609 if (!rinfo || !rinfo->dir_nr)
607610 return true;
608611 chunk_offset = rinfo->dir_entries[0].offset;
@@ -612,7 +615,7 @@ static bool need_reset_readdir(struct ceph_file_info *fi, loff_t new_pos) · 3 unmodified lines
612615
613616 static loff_t ceph_dir_llseek(struct file *file, loff_t offset, int whence)
614617 {
615− struct ceph_file_info *fi = file->private_data;
618+ struct ceph_dir_file_info *dfi = file->private_data;
616619 struct inode *inode = file->f_mapping->host;
617620 loff_t retval;
618621
@@ -630,20 +633,20 @@ static loff_t ceph_dir_llseek(struct file *file, loff_t offset, int whence) · 11 unmodified lines
630633 }
631634
632635 if (offset >= 0) {
633− if (need_reset_readdir(fi, offset)) {
636+ if (need_reset_readdir(dfi, offset)) {
634637 dout("dir_llseek dropping %p content\n", file);
635− reset_readdir(fi);
638+ reset_readdir(dfi);
636639 } else if (is_hash_order(offset) && offset > file->f_pos) {
637640 /* for hash offset, we don't know if a forward seek
638641 * is within same frag */
639− fi->dir_release_count = 0;
640− fi->readdir_cache_idx = -1;
642+ dfi->dir_release_count = 0;
643+ dfi->readdir_cache_idx = -1;
641644 }
642645
643646 if (offset != file->f_pos) {
644647 file->f_pos = offset;
645648 file->f_version = 0;
646− fi->flags &= ~CEPH_F_ATEND;
649+ dfi->file_info.flags &= ~CEPH_F_ATEND;
647650 }
648651 retval = offset;
649652 }
@@ -824,6 +827,9 @@ static int ceph_mknod(struct inode *dir, struct dentry *dentry, · 174 unmodified lines
824827 if (ceph_snap(dir) != CEPH_NOSNAP)
825828 return -EROFS;
826829
830+ if (ceph_quota_is_max_files_exceeded(dir))
831+ return -EDQUOT;
832+
827833 err = ceph_pre_init_acls(dir, &mode, &acls);
828834 if (err < 0)
829835 return err;
@@ -877,6 +883,9 @@ static int ceph_symlink(struct inode *dir, struct dentry *dentry, · 47 unmodified lines
877883 if (ceph_snap(dir) != CEPH_NOSNAP)
878884 return -EROFS;
879885
886+ if (ceph_quota_is_max_files_exceeded(dir))
887+ return -EDQUOT;
888+
880889 dout("symlink in dir %p dentry %p to '%s'\n", dir, dentry, dest);
881890 req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SYMLINK, USE_AUTH_MDS);
882891 if (IS_ERR(req)) {
@@ -926,6 +935,12 @@ static int ceph_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) · 43 unmodified lines
926935 goto out;
927936 }
928937
938+ if (op == CEPH_MDS_OP_MKDIR &&
939+ ceph_quota_is_max_files_exceeded(dir)) {
940+ err = -EDQUOT;
941+ goto out;
942+ }
943+
929944 mode |= S_IFDIR;
930945 err = ceph_pre_init_acls(dir, &mode, &acls);
931946 if (err < 0)
@@ -1065,6 +1080,11 @@ static int ceph_rename(struct inode *old_dir, struct dentry *old_dentry, · 133 unmodified lines
10651080 else
10661081 return -EROFS;
10671082 }
1083+ /* don't allow cross-quota renames */
1084+ if ((old_dir != new_dir) &&
1085+ (!ceph_quota_is_same_realm(old_dir, new_dir)))
1086+ return -EXDEV;
1087+
10681088 dout("rename dir %p dentry %p to dir %p dentry %p\n",
10691089 old_dir, old_dentry, new_dir, new_dentry);
10701090 req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS);
@@ -1351,7 +1371,7 @@ static void ceph_d_prune(struct dentry *dentry) · 280 unmodified lines
13511371 static ssize_t ceph_read_dir(struct file *file, char __user *buf, size_t size,
13521372 loff_t *ppos)
13531373 {
1354− struct ceph_file_info *cf = file->private_data;
1374+ struct ceph_dir_file_info *dfi = file->private_data;
13551375 struct inode *inode = file_inode(file);
13561376 struct ceph_inode_info *ci = ceph_inode(inode);
13571377 int left;
@@ -1360,12 +1380,12 @@ static ssize_t ceph_read_dir(struct file *file, char __user *buf, size_t size, · 2 unmodified lines
13601380 if (!ceph_test_mount_opt(ceph_sb_to_client(inode->i_sb), DIRSTAT))
13611381 return -EISDIR;
13621382
1363− if (!cf->dir_info) {
1364− cf->dir_info = kmalloc(bufsize, GFP_KERNEL);
1365− if (!cf->dir_info)
1383+ if (!dfi->dir_info) {
1384+ dfi->dir_info = kmalloc(bufsize, GFP_KERNEL);
1385+ if (!dfi->dir_info)
13661386 return -ENOMEM;
1367− cf->dir_info_len =
1368− snprintf(cf->dir_info, bufsize,
1387+ dfi->dir_info_len =
1388+ snprintf(dfi->dir_info, bufsize,
13691389 "entries: %20lld\n"
13701390 " files: %20lld\n"
13711391 " subdirs: %20lld\n"
@@ -1385,10 +1405,10 @@ static ssize_t ceph_read_dir(struct file *file, char __user *buf, size_t size, · 13 unmodified lines
13851405 (long)ci->i_rctime.tv_nsec);
13861406 }
13871407
1388− if (*ppos >= cf->dir_info_len)
1408+ if (*ppos >= dfi->dir_info_len)
13891409 return 0;
1390− size = min_t(unsigned, size, cf->dir_info_len-*ppos);
1391− left = copy_to_user(buf, cf->dir_info + *ppos, size);
1410+ size = min_t(unsigned, size, dfi->dir_info_len-*ppos);
1411+ left = copy_to_user(buf, dfi->dir_info + *ppos, size);
13921412 if (left == size)
13931413 return -EFAULT;
13941414 *ppos += (size - left);
fs/ceph/file.c+87−30
@@ -30,6 +30,8 @@ static __le32 ceph_flags_sys2wire(u32 flags) · 29 unmodified lines
3030 break;
3131 }
3232
33+ flags &= ~O_ACCMODE;
34+
3335 #define ceph_sys2wire(a) if (flags & a) { wire_flags |= CEPH_##a; flags &= ~a; }
3436
3537 ceph_sys2wire(O_CREAT);
@@ -41,7 +43,7 @@ static __le32 ceph_flags_sys2wire(u32 flags) · 5 unmodified lines
4143 #undef ceph_sys2wire
4244
4345 if (flags)
44− dout("unused open flags: %x", flags);
46+ dout("unused open flags: %x\n", flags);
4547
4648 return cpu_to_le32(wire_flags);
4749 }
@@ -159,13 +161,50 @@ out: · 111 unmodified lines
159161 return req;
160162 }
161163
164+static int ceph_init_file_info(struct inode *inode, struct file *file,
165+ int fmode, bool isdir)
166+{
167+ struct ceph_file_info *fi;
168+
169+ dout("%s %p %p 0%o (%s)\n", __func__, inode, file,
170+ inode->i_mode, isdir ? "dir" : "regular");
171+ BUG_ON(inode->i_fop->release != ceph_release);
172+
173+ if (isdir) {
174+ struct ceph_dir_file_info *dfi =
175+ kmem_cache_zalloc(ceph_dir_file_cachep, GFP_KERNEL);
176+ if (!dfi) {
177+ ceph_put_fmode(ceph_inode(inode), fmode); /* clean up */
178+ return -ENOMEM;
179+ }
180+
181+ file->private_data = dfi;
182+ fi = &dfi->file_info;
183+ dfi->next_offset = 2;
184+ dfi->readdir_cache_idx = -1;
185+ } else {
186+ fi = kmem_cache_zalloc(ceph_file_cachep, GFP_KERNEL);
187+ if (!fi) {
188+ ceph_put_fmode(ceph_inode(inode), fmode); /* clean up */
189+ return -ENOMEM;
190+ }
191+
192+ file->private_data = fi;
193+ }
194+
195+ fi->fmode = fmode;
196+ spin_lock_init(&fi->rw_contexts_lock);
197+ INIT_LIST_HEAD(&fi->rw_contexts);
198+
199+ return 0;
200+}
201+
162202 /*
163203 * initialize private struct file data.
164204 * if we fail, clean up by dropping fmode reference on the ceph_inode
165205 */
166206 static int ceph_init_file(struct inode *inode, struct file *file, int fmode)
167207 {
168− struct ceph_file_info *cf;
169208 int ret = 0;
170209
171210 switch (inode->i_mode & S_IFMT) {
@@ -173,22 +212,10 @@ static int ceph_init_file(struct inode *inode, struct file *file, int fmode) · 1 unmodified line
173212 ceph_fscache_register_inode_cookie(inode);
174213 ceph_fscache_file_set_cookie(inode, file);
175214 case S_IFDIR:
176− dout("init_file %p %p 0%o (regular)\n", inode, file,
177− inode->i_mode);
178− cf = kmem_cache_zalloc(ceph_file_cachep, GFP_KERNEL);
179− if (!cf) {
180− ceph_put_fmode(ceph_inode(inode), fmode); /* clean up */
181− return -ENOMEM;
182− }
183− cf->fmode = fmode;
184−
185− spin_lock_init(&cf->rw_contexts_lock);
186− INIT_LIST_HEAD(&cf->rw_contexts);
187−
188− cf->next_offset = 2;
189− cf->readdir_cache_idx = -1;
190− file->private_data = cf;
191− BUG_ON(inode->i_fop->release != ceph_release);
215+ ret = ceph_init_file_info(inode, file, fmode,
216+ S_ISDIR(inode->i_mode));
217+ if (ret)
218+ return ret;
192219 break;
193220
194221 case S_IFLNK:
@@ -278,11 +305,11 @@ int ceph_open(struct inode *inode, struct file *file) · 83 unmodified lines
278305 struct ceph_fs_client *fsc = ceph_sb_to_client(inode->i_sb);
279306 struct ceph_mds_client *mdsc = fsc->mdsc;
280307 struct ceph_mds_request *req;
281− struct ceph_file_info *cf = file->private_data;
308+ struct ceph_file_info *fi = file->private_data;
282309 int err;
283310 int flags, fmode, wanted;
284311
285− if (cf) {
312+ if (fi) {
286313 dout("open file %p is already opened\n", file);
287314 return 0;
288315 }
@@ -375,7 +402,7 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry, · 86 unmodified lines
375402 struct ceph_mds_request *req;
376403 struct dentry *dn;
377404 struct ceph_acls_info acls = {};
378− int mask;
405+ int mask;
379406 int err;
380407
381408 dout("atomic_open %p dentry %p '%pd' %s flags %d mode 0%o\n",
@@ -386,6 +413,8 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry, · 4 unmodified lines
386413 return -ENAMETOOLONG;
387414
388415 if (flags & O_CREAT) {
416+ if (ceph_quota_is_max_files_exceeded(dir))
417+ return -EDQUOT;
389418 err = ceph_pre_init_acls(dir, &mode, &acls);
390419 if (err < 0)
391420 return err;
@@ -460,16 +489,27 @@ out_acl: · 68 unmodified lines
460489 int ceph_release(struct inode *inode, struct file *file)
461490 {
462491 struct ceph_inode_info *ci = ceph_inode(inode);
463− struct ceph_file_info *cf = file->private_data;
464492
465− dout("release inode %p file %p\n", inode, file);
466− ceph_put_fmode(ci, cf->fmode);
467− if (cf->last_readdir)
468− ceph_mdsc_put_request(cf->last_readdir);
469− kfree(cf->last_name);
470− kfree(cf->dir_info);
471− WARN_ON(!list_empty(&cf->rw_contexts));
472− kmem_cache_free(ceph_file_cachep, cf);
493+ if (S_ISDIR(inode->i_mode)) {
494+ struct ceph_dir_file_info *dfi = file->private_data;
495+ dout("release inode %p dir file %p\n", inode, file);
496+ WARN_ON(!list_empty(&dfi->file_info.rw_contexts));
497+
498+ ceph_put_fmode(ci, dfi->file_info.fmode);
499+
500+ if (dfi->last_readdir)
501+ ceph_mdsc_put_request(dfi->last_readdir);
502+ kfree(dfi->last_name);
503+ kfree(dfi->dir_info);
504+ kmem_cache_free(ceph_dir_file_cachep, dfi);
505+ } else {
506+ struct ceph_file_info *fi = file->private_data;
507+ dout("release inode %p regular file %p\n", inode, file);
508+ WARN_ON(!list_empty(&fi->rw_contexts));
509+
510+ ceph_put_fmode(ci, fi->fmode);
511+ kmem_cache_free(ceph_file_cachep, fi);
512+ }
473513
474514 /* wake up anyone waiting for caps on this inode */
475515 wake_up_all(&ci->i_cap_wq);
@@ -1338,6 +1378,11 @@ retry_snap: · 862 unmodified lines
13381378
13391379 pos = iocb->ki_pos;
13401380 count = iov_iter_count(from);
1381+ if (ceph_quota_is_max_bytes_exceeded(inode, pos + count)) {
1382+ err = -EDQUOT;
1383+ goto out;
1384+ }
1385+
13411386 err = file_remove_privs(file);
13421387 if (err)
13431388 goto out;
@@ -1419,6 +1464,7 @@ retry_snap: · 75 unmodified lines
14191464
14201465 if (written >= 0) {
14211466 int dirty;
1467+
14221468 spin_lock(&ci->i_ceph_lock);
14231469 ci->i_inline_version = CEPH_INLINE_NONE;
14241470 dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_FILE_WR,
@@ -1426,6 +1472,8 @@ retry_snap: · 1 unmodified line
14261472 spin_unlock(&ci->i_ceph_lock);
14271473 if (dirty)
14281474 __mark_inode_dirty(inode, dirty);
1475+ if (ceph_quota_is_max_bytes_approaching(inode, iocb->ki_pos))
1476+ ceph_check_caps(ci, CHECK_CAPS_NODELAY, NULL);
14291477 }
14301478
14311479 dout("aio_write %p %llx.%llx %llu~%u dropping cap refs on %s\n",
@@ -1668,6 +1716,12 @@ static long ceph_fallocate(struct file *file, int mode, · 236 unmodified lines
16681716 goto unlock;
16691717 }
16701718
1719+ if (!(mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE)) &&
1720+ ceph_quota_is_max_bytes_exceeded(inode, offset + length)) {
1721+ ret = -EDQUOT;
1722+ goto unlock;
1723+ }
1724+
16711725 if (ceph_osdmap_flag(osdc, CEPH_OSDMAP_FULL) &&
16721726 !(mode & FALLOC_FL_PUNCH_HOLE)) {
16731727 ret = -ENOSPC;
@@ -1716,6 +1770,9 @@ static long ceph_fallocate(struct file *file, int mode, · 42 unmodified lines
17161770 spin_unlock(&ci->i_ceph_lock);
17171771 if (dirty)
17181772 __mark_inode_dirty(inode, dirty);
1773+ if ((endoff > size) &&
1774+ ceph_quota_is_max_bytes_approaching(inode, endoff))
1775+ ceph_check_caps(ci, CHECK_CAPS_NODELAY, NULL);
17191776 }
17201777
17211778 ceph_put_cap_refs(ci, got);
fs/ceph/inode.c+15−11
@@ -441,6 +441,9 @@ struct inode *ceph_alloc_inode(struct super_block *sb) · 440 unmodified lines
441441 atomic64_set(&ci->i_complete_seq[1], 0);
442442 ci->i_symlink = NULL;
443443
444+ ci->i_max_bytes = 0;
445+ ci->i_max_files = 0;
446+
444447 memset(&ci->i_dir_layout, 0, sizeof(ci->i_dir_layout));
445448 RCU_INIT_POINTER(ci->i_layout.pool_ns, NULL);
446449
@@ -536,6 +539,9 @@ void ceph_destroy_inode(struct inode *inode) · 89 unmodified lines
536539
537540 ceph_queue_caps_release(inode);
538541
542+ if (__ceph_has_any_quota(ci))
543+ ceph_adjust_quota_realms_count(inode, false);
544+
539545 /*
540546 * we may still have a snap_realm reference if there are stray
541547 * caps in i_snap_caps.
@@ -548,6 +554,9 @@ void ceph_destroy_inode(struct inode *inode) · 6 unmodified lines
548554 dout(" dropping residual ref to snap realm %p\n", realm);
549555 spin_lock(&realm->inodes_with_caps_lock);
550556 list_del_init(&ci->i_snap_realm_item);
557+ ci->i_snap_realm = NULL;
558+ if (realm->ino == ci->i_vino.ino)
559+ realm->inode = NULL;
551560 spin_unlock(&realm->inodes_with_caps_lock);
552561 ceph_put_snap_realm(mdsc, realm);
553562 }
@@ -790,6 +799,8 @@ static int fill_inode(struct inode *inode, struct page *locked_page, · 236 unmodified lines
790799 inode->i_rdev = le32_to_cpu(info->rdev);
791800 inode->i_blkbits = fls(le32_to_cpu(info->layout.fl_stripe_unit)) - 1;
792801
802+ __ceph_update_quota(ci, iinfo->max_bytes, iinfo->max_files);
803+
793804 if ((new_version || (new_issued & CEPH_CAP_AUTH_SHARED)) &&
794805 (issued & CEPH_CAP_AUTH_EXCL) == 0) {
795806 inode->i_mode = le32_to_cpu(info->mode);
@@ -1867,20 +1878,9 @@ retry: · 1071 unmodified lines
18671878 * possibly truncate them.. so write AND block!
18681879 */
18691880 if (ci->i_wrbuffer_ref_head < ci->i_wrbuffer_ref) {
1870− struct ceph_cap_snap *capsnap;
1871− to = ci->i_truncate_size;
1872− list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) {
1873− // MDS should have revoked Frw caps
1874− WARN_ON_ONCE(capsnap->writing);
1875− if (capsnap->dirty_pages && capsnap->size > to)
1876− to = capsnap->size;
1877− }
18781881 spin_unlock(&ci->i_ceph_lock);
18791882 dout("__do_pending_vmtruncate %p flushing snaps first\n",
18801883 inode);
1881−
1882− truncate_pagecache(inode, to);
1883−
18841884 filemap_write_and_wait_range(&inode->i_data, 0,
18851885 inode->i_sb->s_maxbytes);
18861886 goto retry;
@@ -2152,6 +2152,10 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) · 265 unmodified lines
21522152 if (err != 0)
21532153 return err;
21542154
2155+ if ((attr->ia_valid & ATTR_SIZE) &&
2156+ ceph_quota_is_max_bytes_exceeded(inode, attr->ia_size))
2157+ return -EDQUOT;
2158+
21552159 err = __ceph_setattr(inode, attr);
21562160
21572161 if (err >= 0 && (attr->ia_valid & ATTR_MODE))
fs/ceph/ioctl.c+4−9
@@ -5,7 +5,7 @@ · 4 unmodified lines
55 #include "super.h"
66 #include "mds_client.h"
77 #include "ioctl.h"
8−
8+#include <linux/ceph/striper.h>
99
1010 /*
1111 * ioctls
@@ -185,7 +185,7 @@ static long ceph_ioctl_get_dataloc(struct file *file, void __user *arg) · 173 unmodified lines
185185 &ceph_sb_to_client(inode->i_sb)->client->osdc;
186186 struct ceph_object_locator oloc;
187187 CEPH_DEFINE_OID_ONSTACK(oid);
188− u64 len = 1, olen;
188+ u32 xlen;
189189 u64 tmp;
190190 struct ceph_pg pgid;
191191 int r;
@@ -195,13 +195,8 @@ static long ceph_ioctl_get_dataloc(struct file *file, void __user *arg) · 3 unmodified lines
195195 return -EFAULT;
196196
197197 down_read(&osdc->lock);
198− r = ceph_calc_file_object_mapping(&ci->i_layout, dl.file_offset, len,
199− &dl.object_no, &dl.object_offset,
200− &olen);
201− if (r < 0) {
202− up_read(&osdc->lock);
203− return -EIO;
204− }
198+ ceph_calc_file_object_mapping(&ci->i_layout, dl.file_offset, 1,
199+ &dl.object_no, &dl.object_offset, &xlen);
205200 dl.file_offset -= dl.object_offset;
206201 dl.object_size = ci->i_layout.object_size;
207202 dl.block_size = ci->i_layout.stripe_unit;
fs/ceph/locks.c+10−10
@@ -95,7 +95,7 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct inode *inode, · 94 unmodified lines
9595 owner = secure_addr(fl->fl_owner);
9696
9797 dout("ceph_lock_message: rule: %d, op: %d, owner: %llx, pid: %llu, "
98− "start: %llu, length: %llu, wait: %d, type: %d", (int)lock_type,
98+ "start: %llu, length: %llu, wait: %d, type: %d\n", (int)lock_type,
9999 (int)operation, owner, (u64)fl->fl_pid, fl->fl_start, length,
100100 wait, fl->fl_type);
101101
@@ -132,7 +132,7 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct inode *inode, · 30 unmodified lines
132132 }
133133 ceph_mdsc_put_request(req);
134134 dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, "
135− "length: %llu, wait: %d, type: %d, err code %d", (int)lock_type,
135+ "length: %llu, wait: %d, type: %d, err code %d\n", (int)lock_type,
136136 (int)operation, (u64)fl->fl_pid, fl->fl_start,
137137 length, wait, fl->fl_type, err);
138138 return err;
@@ -226,7 +226,7 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl) · 87 unmodified lines
226226 if (__mandatory_lock(file->f_mapping->host) && fl->fl_type != F_UNLCK)
227227 return -ENOLCK;
228228
229− dout("ceph_lock, fl_owner: %p", fl->fl_owner);
229+ dout("ceph_lock, fl_owner: %p\n", fl->fl_owner);
230230
231231 /* set wait bit as appropriate, then make command as Ceph expects it*/
232232 if (IS_GETLK(cmd))
@@ -264,7 +264,7 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl) · 31 unmodified lines
264264 err = ceph_lock_message(CEPH_LOCK_FCNTL, op, inode, lock_cmd, wait, fl);
265265 if (!err) {
266266 if (op == CEPH_MDS_OP_SETFILELOCK) {
267− dout("mds locked, locking locally");
267+ dout("mds locked, locking locally\n");
268268 err = posix_lock_file(file, fl, NULL);
269269 if (err) {
270270 /* undo! This should only happen if
@@ -272,7 +272,7 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl) · 1 unmodified line
272272 * deadlock. */
273273 ceph_lock_message(CEPH_LOCK_FCNTL, op, inode,
274274 CEPH_LOCK_UNLOCK, 0, fl);
275− dout("got %d on posix_lock_file, undid lock",
275+ dout("got %d on posix_lock_file, undid lock\n",
276276 err);
277277 }
278278 }
@@ -294,7 +294,7 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl) · 15 unmodified lines
294294 if (fl->fl_type & LOCK_MAND)
295295 return -EOPNOTSUPP;
296296
297− dout("ceph_flock, fl_file: %p", fl->fl_file);
297+ dout("ceph_flock, fl_file: %p\n", fl->fl_file);
298298
299299 spin_lock(&ci->i_ceph_lock);
300300 if (ci->i_ceph_flags & CEPH_I_ERROR_FILELOCK) {
@@ -329,7 +329,7 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl) · 28 unmodified lines
329329 ceph_lock_message(CEPH_LOCK_FLOCK,
330330 CEPH_MDS_OP_SETFILELOCK,
331331 inode, CEPH_LOCK_UNLOCK, 0, fl);
332− dout("got %d on locks_lock_file_wait, undid lock", err);
332+ dout("got %d on locks_lock_file_wait, undid lock\n", err);
333333 }
334334 }
335335 return err;
@@ -356,7 +356,7 @@ void ceph_count_locks(struct inode *inode, int *fcntl_count, int *flock_count) · 20 unmodified lines
356356 ++(*flock_count);
357357 spin_unlock(&ctx->flc_lock);
358358 }
359− dout("counted %d flock locks and %d fcntl locks",
359+ dout("counted %d flock locks and %d fcntl locks\n",
360360 *flock_count, *fcntl_count);
361361 }
362362
@@ -384,7 +384,7 @@ static int lock_to_ceph_filelock(struct file_lock *lock, · 21 unmodified lines
384384 cephlock->type = CEPH_LOCK_UNLOCK;
385385 break;
386386 default:
387− dout("Have unknown lock type %d", lock->fl_type);
387+ dout("Have unknown lock type %d\n", lock->fl_type);
388388 err = -EINVAL;
389389 }
390390
@@ -407,7 +407,7 @@ int ceph_encode_locks_to_buffer(struct inode *inode, · 16 unmodified lines
407407 int seen_flock = 0;
408408 int l = 0;
409409
410− dout("encoding %d flock and %d fcntl locks", num_flock_locks,
410+ dout("encoding %d flock and %d fcntl locks\n", num_flock_locks,
411411 num_fcntl_locks);
412412
413413 if (!ctx)
fs/ceph/mds_client.c+58−29
@@ -100,6 +100,26 @@ static int parse_reply_info_in(void **p, void *end, · 99 unmodified lines
100100 } else
101101 info->inline_version = CEPH_INLINE_NONE;
102102
103+ if (features & CEPH_FEATURE_MDS_QUOTA) {
104+ u8 struct_v, struct_compat;
105+ u32 struct_len;
106+
107+ /*
108+ * both struct_v and struct_compat are expected to be >= 1
109+ */
110+ ceph_decode_8_safe(p, end, struct_v, bad);
111+ ceph_decode_8_safe(p, end, struct_compat, bad);
112+ if (!struct_v || !struct_compat)
113+ goto bad;
114+ ceph_decode_32_safe(p, end, struct_len, bad);
115+ ceph_decode_need(p, end, struct_len, bad);
116+ ceph_decode_64_safe(p, end, info->max_bytes, bad);
117+ ceph_decode_64_safe(p, end, info->max_files, bad);
118+ } else {
119+ info->max_bytes = 0;
120+ info->max_files = 0;
121+ }
122+
103123 info->pool_ns_len = 0;
104124 info->pool_ns_data = NULL;
105125 if (features & CEPH_FEATURE_FS_FILE_LAYOUT_V2) {
@@ -384,7 +404,7 @@ static struct ceph_mds_session *get_session(struct ceph_mds_session *s) · 278 unmodified lines
384404 refcount_read(&s->s_ref)-1, refcount_read(&s->s_ref));
385405 return s;
386406 } else {
387− dout("mdsc get_session %p 0 -- FAIL", s);
407+ dout("mdsc get_session %p 0 -- FAIL\n", s);
388408 return NULL;
389409 }
390410 }
@@ -419,9 +439,10 @@ struct ceph_mds_session *__ceph_lookup_mds_session(struct ceph_mds_client *mdsc, · 28 unmodified lines
419439
420440 static bool __have_session(struct ceph_mds_client *mdsc, int mds)
421441 {
422− if (mds >= mdsc->max_sessions)
442+ if (mds >= mdsc->max_sessions || !mdsc->sessions[mds])
423443 return false;
424− return mdsc->sessions[mds];
444+ else
445+ return true;
425446 }
426447
427448 static int __verify_registered_session(struct ceph_mds_client *mdsc,
@@ -448,6 +469,25 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc, · 20 unmodified lines
448469 s = kzalloc(sizeof(*s), GFP_NOFS);
449470 if (!s)
450471 return ERR_PTR(-ENOMEM);
472+
473+ if (mds >= mdsc->max_sessions) {
474+ int newmax = 1 << get_count_order(mds + 1);
475+ struct ceph_mds_session **sa;
476+
477+ dout("%s: realloc to %d\n", __func__, newmax);
478+ sa = kcalloc(newmax, sizeof(void *), GFP_NOFS);
479+ if (!sa)
480+ goto fail_realloc;
481+ if (mdsc->sessions) {
482+ memcpy(sa, mdsc->sessions,
483+ mdsc->max_sessions * sizeof(void *));
484+ kfree(mdsc->sessions);
485+ }
486+ mdsc->sessions = sa;
487+ mdsc->max_sessions = newmax;
488+ }
489+
490+ dout("%s: mds%d\n", __func__, mds);
451491 s->s_mdsc = mdsc;
452492 s->s_mds = mds;
453493 s->s_state = CEPH_MDS_SESSION_NEW;
@@ -476,23 +516,6 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc, · 22 unmodified lines
476516 INIT_LIST_HEAD(&s->s_cap_releases);
477517 INIT_LIST_HEAD(&s->s_cap_flushing);
478518
479− dout("register_session mds%d\n", mds);
480− if (mds >= mdsc->max_sessions) {
481− int newmax = 1 << get_count_order(mds+1);
482− struct ceph_mds_session **sa;
483−
484− dout("register_session realloc to %d\n", newmax);
485− sa = kcalloc(newmax, sizeof(void *), GFP_NOFS);
486− if (!sa)
487− goto fail_realloc;
488− if (mdsc->sessions) {
489− memcpy(sa, mdsc->sessions,
490− mdsc->max_sessions * sizeof(void *));
491− kfree(mdsc->sessions);
492− }
493− mdsc->sessions = sa;
494− mdsc->max_sessions = newmax;
495− }
496519 mdsc->sessions[mds] = s;
497520 atomic_inc(&mdsc->num_sessions);
498521 refcount_inc(&s->s_ref); /* one ref to sessions[], one to caller */
@@ -2531,10 +2554,10 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) · 2032 unmodified lines
25312554 * Otherwise we just have to return an ESTALE
25322555 */
25332556 if (result == -ESTALE) {
2534− dout("got ESTALE on request %llu", req->r_tid);
2557+ dout("got ESTALE on request %llu\n", req->r_tid);
25352558 req->r_resend_mds = -1;
25362559 if (req->r_direct_mode != USE_AUTH_MDS) {
2537− dout("not using auth, setting for that now");
2560+ dout("not using auth, setting for that now\n");
25382561 req->r_direct_mode = USE_AUTH_MDS;
25392562 __do_request(mdsc, req);
25402563 mutex_unlock(&mdsc->mutex);
@@ -2542,13 +2565,13 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) · 1 unmodified line
25422565 } else {
25432566 int mds = __choose_mds(mdsc, req);
25442567 if (mds >= 0 && mds != req->r_session->s_mds) {
2545− dout("but auth changed, so resending");
2568+ dout("but auth changed, so resending\n");
25462569 __do_request(mdsc, req);
25472570 mutex_unlock(&mdsc->mutex);
25482571 goto out;
25492572 }
25502573 }
2551− dout("have to return ESTALE on request %llu", req->r_tid);
2574+ dout("have to return ESTALE on request %llu\n", req->r_tid);
25522575 }
25532576
25542577
@@ -3470,13 +3493,12 @@ void ceph_mdsc_lease_send_msg(struct ceph_mds_session *session, · 915 unmodified lines
34703493 }
34713494
34723495 /*
3473− * drop all leases (and dentry refs) in preparation for umount
3496+ * lock unlock sessions, to wait ongoing session activities
34743497 */
3475−static void drop_leases(struct ceph_mds_client *mdsc)
3498+static void lock_unlock_sessions(struct ceph_mds_client *mdsc)
34763499 {
34773500 int i;
34783501
3479− dout("drop_leases\n");
34803502 mutex_lock(&mdsc->mutex);
34813503 for (i = 0; i < mdsc->max_sessions; i++) {
34823504 struct ceph_mds_session *s = __ceph_lookup_mds_session(mdsc, i);
@@ -3572,7 +3594,6 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc) · 89 unmodified lines
35723594 if (!mdsc)
35733595 return -ENOMEM;
35743596 mdsc->fsc = fsc;
3575− fsc->mdsc = mdsc;
35763597 mutex_init(&mdsc->mutex);
35773598 mdsc->mdsmap = kzalloc(sizeof(*mdsc->mdsmap), GFP_NOFS);
35783599 if (!mdsc->mdsmap) {
@@ -3580,6 +3601,7 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc) · 1 unmodified line
35803601 return -ENOMEM;
35813602 }
35823603
3604+ fsc->mdsc = mdsc;
35833605 init_completion(&mdsc->safe_umount_waiters);
35843606 init_waitqueue_head(&mdsc->session_close_wq);
35853607 INIT_LIST_HEAD(&mdsc->waiting_for_map);
@@ -3587,6 +3609,7 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc) · 1 unmodified line
35873609 atomic_set(&mdsc->num_sessions, 0);
35883610 mdsc->max_sessions = 0;
35893611 mdsc->stopping = 0;
3612+ atomic64_set(&mdsc->quotarealms_count, 0);
35903613 mdsc->last_snap_seq = 0;
35913614 init_rwsem(&mdsc->snap_rwsem);
35923615 mdsc->snap_realms = RB_ROOT;
@@ -3660,7 +3683,7 @@ void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc) · 67 unmodified lines
36603683 dout("pre_umount\n");
36613684 mdsc->stopping = 1;
36623685
3663− drop_leases(mdsc);
3686+ lock_unlock_sessions(mdsc);
36643687 ceph_flush_dirty_caps(mdsc);
36653688 wait_requests(mdsc);
36663689
@@ -3858,6 +3881,9 @@ void ceph_mdsc_destroy(struct ceph_fs_client *fsc) · 191 unmodified lines
38583881 struct ceph_mds_client *mdsc = fsc->mdsc;
38593882 dout("mdsc_destroy %p\n", mdsc);
38603883
3884+ if (!mdsc)
3885+ return;
3886+
38613887 /* flush out any connection work with references to us */
38623888 ceph_msgr_flush();
38633889
@@ -4077,6 +4103,9 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg) · 213 unmodified lines
40774103 case CEPH_MSG_CLIENT_LEASE:
40784104 handle_lease(mdsc, s, msg);
40794105 break;
4106+ case CEPH_MSG_CLIENT_QUOTA:
4107+ ceph_handle_quota(mdsc, s, msg);
4108+ break;
40804109
40814110 default:
40824111 pr_err("received unknown message type %d %s\n", type,
fs/ceph/mds_client.h+4−0
@@ -49,6 +49,8 @@ struct ceph_mds_reply_info_in { · 48 unmodified lines
4949 char *inline_data;
5050 u32 pool_ns_len;
5151 char *pool_ns_data;
52+ u64 max_bytes;
53+ u64 max_files;
5254 };
5355
5456 struct ceph_mds_reply_dir_entry {
@@ -312,6 +314,8 @@ struct ceph_mds_client { · 257 unmodified lines
312314 int max_sessions; /* len of s_mds_sessions */
313315 int stopping; /* true if shutting down */
314316
317+ atomic64_t quotarealms_count; /* # realms with quota */
318+
315319 /*
316320 * snap_rwsem will cover cap linkage into snaprealms, and
317321 * realm snap contexts. (later, we can do per-realm snap
fs/ceph/quota.c+361−0
@@ -0,0 +1,361 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * quota.c - CephFS quota
4+ *
5+ * Copyright (C) 2017-2018 SUSE
6+ *
7+ * This program is free software; you can redistribute it and/or
8+ * modify it under the terms of the GNU General Public License
9+ * as published by the Free Software Foundation; either version 2
10+ * of the License, or (at your option) any later version.
11+ *
12+ * This program is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ * GNU General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU General Public License
18+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
19+ */
20+
21+#include <linux/statfs.h>
22+
23+#include "super.h"
24+#include "mds_client.h"
25+
26+void ceph_adjust_quota_realms_count(struct inode *inode, bool inc)
27+{
28+ struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc;
29+ if (inc)
30+ atomic64_inc(&mdsc->quotarealms_count);
31+ else
32+ atomic64_dec(&mdsc->quotarealms_count);
33+}
34+
35+static inline bool ceph_has_realms_with_quotas(struct inode *inode)
36+{
37+ struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc;
38+ return atomic64_read(&mdsc->quotarealms_count) > 0;
39+}
40+
41+void ceph_handle_quota(struct ceph_mds_client *mdsc,
42+ struct ceph_mds_session *session,
43+ struct ceph_msg *msg)
44+{
45+ struct super_block *sb = mdsc->fsc->sb;
46+ struct ceph_mds_quota *h = msg->front.iov_base;
47+ struct ceph_vino vino;
48+ struct inode *inode;
49+ struct ceph_inode_info *ci;
50+
51+ if (msg->front.iov_len != sizeof(*h)) {
52+ pr_err("%s corrupt message mds%d len %d\n", __func__,
53+ session->s_mds, (int)msg->front.iov_len);
54+ ceph_msg_dump(msg);
55+ return;
56+ }
57+
58+ /* increment msg sequence number */
59+ mutex_lock(&session->s_mutex);
60+ session->s_seq++;
61+ mutex_unlock(&session->s_mutex);
62+
63+ /* lookup inode */
64+ vino.ino = le64_to_cpu(h->ino);
65+ vino.snap = CEPH_NOSNAP;
66+ inode = ceph_find_inode(sb, vino);
67+ if (!inode) {
68+ pr_warn("Failed to find inode %llu\n", vino.ino);
69+ return;
70+ }
71+ ci = ceph_inode(inode);
72+
73+ spin_lock(&ci->i_ceph_lock);
74+ ci->i_rbytes = le64_to_cpu(h->rbytes);
75+ ci->i_rfiles = le64_to_cpu(h->rfiles);
76+ ci->i_rsubdirs = le64_to_cpu(h->rsubdirs);
77+ __ceph_update_quota(ci, le64_to_cpu(h->max_bytes),
78+ le64_to_cpu(h->max_files));
79+ spin_unlock(&ci->i_ceph_lock);
80+
81+ iput(inode);
82+}
83+
84+/*
85+ * This function walks through the snaprealm for an inode and returns the
86+ * ceph_snap_realm for the first snaprealm that has quotas set (either max_files
87+ * or max_bytes). If the root is reached, return the root ceph_snap_realm
88+ * instead.
89+ *
90+ * Note that the caller is responsible for calling ceph_put_snap_realm() on the
91+ * returned realm.
92+ */
93+static struct ceph_snap_realm *get_quota_realm(struct ceph_mds_client *mdsc,
94+ struct inode *inode)
95+{
96+ struct ceph_inode_info *ci = NULL;
97+ struct ceph_snap_realm *realm, *next;
98+ struct inode *in;
99+ bool has_quota;
100+
101+ if (ceph_snap(inode) != CEPH_NOSNAP)
102+ return NULL;
103+
104+ realm = ceph_inode(inode)->i_snap_realm;
105+ if (realm)
106+ ceph_get_snap_realm(mdsc, realm);
107+ else
108+ pr_err_ratelimited("get_quota_realm: ino (%llx.%llx) "
109+ "null i_snap_realm\n", ceph_vinop(inode));
110+ while (realm) {
111+ spin_lock(&realm->inodes_with_caps_lock);
112+ in = realm->inode ? igrab(realm->inode) : NULL;
113+ spin_unlock(&realm->inodes_with_caps_lock);
114+ if (!in)
115+ break;
116+
117+ ci = ceph_inode(in);
118+ has_quota = __ceph_has_any_quota(ci);
119+ iput(in);
120+
121+ next = realm->parent;
122+ if (has_quota || !next)
123+ return realm;
124+
125+ ceph_get_snap_realm(mdsc, next);
126+ ceph_put_snap_realm(mdsc, realm);
127+ realm = next;
128+ }
129+ if (realm)
130+ ceph_put_snap_realm(mdsc, realm);
131+
132+ return NULL;
133+}
134+
135+bool ceph_quota_is_same_realm(struct inode *old, struct inode *new)
136+{
137+ struct ceph_mds_client *mdsc = ceph_inode_to_client(old)->mdsc;
138+ struct ceph_snap_realm *old_realm, *new_realm;
139+ bool is_same;
140+
141+ down_read(&mdsc->snap_rwsem);
142+ old_realm = get_quota_realm(mdsc, old);
143+ new_realm = get_quota_realm(mdsc, new);
144+ is_same = (old_realm == new_realm);
145+ up_read(&mdsc->snap_rwsem);
146+
147+ if (old_realm)
148+ ceph_put_snap_realm(mdsc, old_realm);
149+ if (new_realm)
150+ ceph_put_snap_realm(mdsc, new_realm);
151+
152+ return is_same;
153+}
154+
155+enum quota_check_op {
156+ QUOTA_CHECK_MAX_FILES_OP, /* check quota max_files limit */
157+ QUOTA_CHECK_MAX_BYTES_OP, /* check quota max_files limit */
158+ QUOTA_CHECK_MAX_BYTES_APPROACHING_OP /* check if quota max_files
159+ limit is approaching */
160+};
161+
162+/*
163+ * check_quota_exceeded() will walk up the snaprealm hierarchy and, for each
164+ * realm, it will execute quota check operation defined by the 'op' parameter.
165+ * The snaprealm walk is interrupted if the quota check detects that the quota
166+ * is exceeded or if the root inode is reached.
167+ */
168+static bool check_quota_exceeded(struct inode *inode, enum quota_check_op op,
169+ loff_t delta)
170+{
171+ struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc;
172+ struct ceph_inode_info *ci;
173+ struct ceph_snap_realm *realm, *next;
174+ struct inode *in;
175+ u64 max, rvalue;
176+ bool exceeded = false;
177+
178+ if (ceph_snap(inode) != CEPH_NOSNAP)
179+ return false;
180+
181+ down_read(&mdsc->snap_rwsem);
182+ realm = ceph_inode(inode)->i_snap_realm;
183+ if (realm)
184+ ceph_get_snap_realm(mdsc, realm);
185+ else
186+ pr_err_ratelimited("check_quota_exceeded: ino (%llx.%llx) "
187+ "null i_snap_realm\n", ceph_vinop(inode));
188+ while (realm) {
189+ spin_lock(&realm->inodes_with_caps_lock);
190+ in = realm->inode ? igrab(realm->inode) : NULL;
191+ spin_unlock(&realm->inodes_with_caps_lock);
192+ if (!in)
193+ break;
194+
195+ ci = ceph_inode(in);
196+ spin_lock(&ci->i_ceph_lock);
197+ if (op == QUOTA_CHECK_MAX_FILES_OP) {
198+ max = ci->i_max_files;
199+ rvalue = ci->i_rfiles + ci->i_rsubdirs;
200+ } else {
201+ max = ci->i_max_bytes;
202+ rvalue = ci->i_rbytes;
203+ }
204+ spin_unlock(&ci->i_ceph_lock);
205+ switch (op) {
206+ case QUOTA_CHECK_MAX_FILES_OP:
207+ exceeded = (max && (rvalue >= max));
208+ break;
209+ case QUOTA_CHECK_MAX_BYTES_OP:
210+ exceeded = (max && (rvalue + delta > max));
211+ break;
212+ case QUOTA_CHECK_MAX_BYTES_APPROACHING_OP:
213+ if (max) {
214+ if (rvalue >= max)
215+ exceeded = true;
216+ else {
217+ /*
218+ * when we're writing more that 1/16th
219+ * of the available space
220+ */
221+ exceeded =
222+ (((max - rvalue) >> 4) < delta);
223+ }
224+ }
225+ break;
226+ default:
227+ /* Shouldn't happen */
228+ pr_warn("Invalid quota check op (%d)\n", op);
229+ exceeded = true; /* Just break the loop */
230+ }
231+ iput(in);
232+
233+ next = realm->parent;
234+ if (exceeded || !next)
235+ break;
236+ ceph_get_snap_realm(mdsc, next);
237+ ceph_put_snap_realm(mdsc, realm);
238+ realm = next;
239+ }
240+ ceph_put_snap_realm(mdsc, realm);
241+ up_read(&mdsc->snap_rwsem);
242+
243+ return exceeded;
244+}
245+
246+/*
247+ * ceph_quota_is_max_files_exceeded - check if we can create a new file
248+ * @inode: directory where a new file is being created
249+ *
250+ * This functions returns true is max_files quota allows a new file to be
251+ * created. It is necessary to walk through the snaprealm hierarchy (until the
252+ * FS root) to check all realms with quotas set.
253+ */
254+bool ceph_quota_is_max_files_exceeded(struct inode *inode)
255+{
256+ if (!ceph_has_realms_with_quotas(inode))
257+ return false;
258+
259+ WARN_ON(!S_ISDIR(inode->i_mode));
260+
261+ return check_quota_exceeded(inode, QUOTA_CHECK_MAX_FILES_OP, 0);
262+}
263+
264+/*
265+ * ceph_quota_is_max_bytes_exceeded - check if we can write to a file
266+ * @inode: inode being written
267+ * @newsize: new size if write succeeds
268+ *
269+ * This functions returns true is max_bytes quota allows a file size to reach
270+ * @newsize; it returns false otherwise.
271+ */
272+bool ceph_quota_is_max_bytes_exceeded(struct inode *inode, loff_t newsize)
273+{
274+ loff_t size = i_size_read(inode);
275+
276+ if (!ceph_has_realms_with_quotas(inode))
277+ return false;
278+
279+ /* return immediately if we're decreasing file size */
280+ if (newsize <= size)
281+ return false;
282+
283+ return check_quota_exceeded(inode, QUOTA_CHECK_MAX_BYTES_OP, (newsize - size));
284+}
285+
286+/*
287+ * ceph_quota_is_max_bytes_approaching - check if we're reaching max_bytes
288+ * @inode: inode being written
289+ * @newsize: new size if write succeeds
290+ *
291+ * This function returns true if the new file size @newsize will be consuming
292+ * more than 1/16th of the available quota space; it returns false otherwise.
293+ */
294+bool ceph_quota_is_max_bytes_approaching(struct inode *inode, loff_t newsize)
295+{
296+ loff_t size = ceph_inode(inode)->i_reported_size;
297+
298+ if (!ceph_has_realms_with_quotas(inode))
299+ return false;
300+
301+ /* return immediately if we're decreasing file size */
302+ if (newsize <= size)
303+ return false;
304+
305+ return check_quota_exceeded(inode, QUOTA_CHECK_MAX_BYTES_APPROACHING_OP,
306+ (newsize - size));
307+}
308+
309+/*
310+ * ceph_quota_update_statfs - if root has quota update statfs with quota status
311+ * @fsc: filesystem client instance
312+ * @buf: statfs to update
313+ *
314+ * If the mounted filesystem root has max_bytes quota set, update the filesystem
315+ * statistics with the quota status.
316+ *
317+ * This function returns true if the stats have been updated, false otherwise.
318+ */
319+bool ceph_quota_update_statfs(struct ceph_fs_client *fsc, struct kstatfs *buf)
320+{
321+ struct ceph_mds_client *mdsc = fsc->mdsc;
322+ struct ceph_inode_info *ci;
323+ struct ceph_snap_realm *realm;
324+ struct inode *in;
325+ u64 total = 0, used, free;
326+ bool is_updated = false;
327+
328+ down_read(&mdsc->snap_rwsem);
329+ realm = get_quota_realm(mdsc, d_inode(fsc->sb->s_root));
330+ up_read(&mdsc->snap_rwsem);
331+ if (!realm)
332+ return false;
333+
334+ spin_lock(&realm->inodes_with_caps_lock);
335+ in = realm->inode ? igrab(realm->inode) : NULL;
336+ spin_unlock(&realm->inodes_with_caps_lock);
337+ if (in) {
338+ ci = ceph_inode(in);
339+ spin_lock(&ci->i_ceph_lock);
340+ if (ci->i_max_bytes) {
341+ total = ci->i_max_bytes >> CEPH_BLOCK_SHIFT;
342+ used = ci->i_rbytes >> CEPH_BLOCK_SHIFT;
343+ /* It is possible for a quota to be exceeded.
344+ * Report 'zero' in that case
345+ */
346+ free = total > used ? total - used : 0;
347+ }
348+ spin_unlock(&ci->i_ceph_lock);
349+ if (total) {
350+ buf->f_blocks = total;
351+ buf->f_bfree = free;
352+ buf->f_bavail = free;
353+ is_updated = true;
354+ }
355+ iput(in);
356+ }
357+ ceph_put_snap_realm(mdsc, realm);
358+
359+ return is_updated;
360+}
361+
fs/ceph/snap.c+2−0
@@ -931,6 +931,8 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc, · 930 unmodified lines
931931 list_add(&ci->i_snap_realm_item,
932932 &realm->inodes_with_caps);
933933 ci->i_snap_realm = realm;
934+ if (realm->ino == ci->i_vino.ino)
935+ realm->inode = inode;
934936 spin_unlock(&realm->inodes_with_caps_lock);
935937
936938 spin_unlock(&ci->i_ceph_lock);
fs/ceph/super.c+39−11
@@ -76,9 +76,18 @@ static int ceph_statfs(struct dentry *dentry, struct kstatfs *buf) · 75 unmodified lines
7676 */
7777 buf->f_bsize = 1 << CEPH_BLOCK_SHIFT;
7878 buf->f_frsize = 1 << CEPH_BLOCK_SHIFT;
79− buf->f_blocks = le64_to_cpu(st.kb) >> (CEPH_BLOCK_SHIFT-10);
80− buf->f_bfree = le64_to_cpu(st.kb_avail) >> (CEPH_BLOCK_SHIFT-10);
81− buf->f_bavail = le64_to_cpu(st.kb_avail) >> (CEPH_BLOCK_SHIFT-10);
79+
80+ /*
81+ * By default use root quota for stats; fallback to overall filesystem
82+ * usage if using 'noquotadf' mount option or if the root dir doesn't
83+ * have max_bytes quota set.
84+ */
85+ if (ceph_test_mount_opt(fsc, NOQUOTADF) ||
86+ !ceph_quota_update_statfs(fsc, buf)) {
87+ buf->f_blocks = le64_to_cpu(st.kb) >> (CEPH_BLOCK_SHIFT-10);
88+ buf->f_bfree = le64_to_cpu(st.kb_avail) >> (CEPH_BLOCK_SHIFT-10);
89+ buf->f_bavail = le64_to_cpu(st.kb_avail) >> (CEPH_BLOCK_SHIFT-10);
90+ }
8291
8392 buf->f_files = le64_to_cpu(st.num_objects);
8493 buf->f_ffree = -1;
@@ -151,6 +160,8 @@ enum { · 66 unmodified lines
151160 Opt_acl,
152161 #endif
153162 Opt_noacl,
163+ Opt_quotadf,
164+ Opt_noquotadf,
154165 };
155166
156167 static match_table_t fsopt_tokens = {
@@ -187,6 +198,8 @@ static match_table_t fsopt_tokens = { · 30 unmodified lines
187198 {Opt_acl, "acl"},
188199 #endif
189200 {Opt_noacl, "noacl"},
201+ {Opt_quotadf, "quotadf"},
202+ {Opt_noquotadf, "noquotadf"},
190203 {-1, NULL}
191204 };
192205
@@ -314,13 +327,16 @@ static int parse_fsopt_token(char *c, void *private) · 121 unmodified lines
314327 break;
315328 case Opt_fscache:
316329 fsopt->flags |= CEPH_MOUNT_OPT_FSCACHE;
330+ kfree(fsopt->fscache_uniq);
331+ fsopt->fscache_uniq = NULL;
317332 break;
318333 case Opt_nofscache:
319334 fsopt->flags &= ~CEPH_MOUNT_OPT_FSCACHE;
335+ kfree(fsopt->fscache_uniq);
336+ fsopt->fscache_uniq = NULL;
320337 break;
321338 case Opt_poolperm:
322339 fsopt->flags &= ~CEPH_MOUNT_OPT_NOPOOLPERM;
323− printk ("pool perm");
324340 break;
325341 case Opt_nopoolperm:
326342 fsopt->flags |= CEPH_MOUNT_OPT_NOPOOLPERM;
@@ -331,6 +347,12 @@ static int parse_fsopt_token(char *c, void *private) · 4 unmodified lines
331347 case Opt_norequire_active_mds:
332348 fsopt->flags |= CEPH_MOUNT_OPT_MOUNTWAIT;
333349 break;
350+ case Opt_quotadf:
351+ fsopt->flags &= ~CEPH_MOUNT_OPT_NOQUOTADF;
352+ break;
353+ case Opt_noquotadf:
354+ fsopt->flags |= CEPH_MOUNT_OPT_NOQUOTADF;
355+ break;
334356 #ifdef CONFIG_CEPH_FS_POSIX_ACL
335357 case Opt_acl:
336358 fsopt->sb_flags |= SB_POSIXACL;
@@ -513,13 +535,12 @@ static int ceph_show_options(struct seq_file *m, struct dentry *root) · 176 unmodified lines
513535 if ((fsopt->flags & CEPH_MOUNT_OPT_DCACHE) == 0)
514536 seq_puts(m, ",nodcache");
515537 if (fsopt->flags & CEPH_MOUNT_OPT_FSCACHE) {
516− if (fsopt->fscache_uniq)
517− seq_printf(m, ",fsc=%s", fsopt->fscache_uniq);
518− else
519− seq_puts(m, ",fsc");
538+ seq_show_option(m, "fsc", fsopt->fscache_uniq);
520539 }
521540 if (fsopt->flags & CEPH_MOUNT_OPT_NOPOOLPERM)
522541 seq_puts(m, ",nopoolperm");
542+ if (fsopt->flags & CEPH_MOUNT_OPT_NOQUOTADF)
543+ seq_puts(m, ",noquotadf");
523544
524545 #ifdef CONFIG_CEPH_FS_POSIX_ACL
525546 if (fsopt->sb_flags & SB_POSIXACL)
@@ -529,7 +550,7 @@ static int ceph_show_options(struct seq_file *m, struct dentry *root) · 3 unmodified lines
529550 #endif
530551
531552 if (fsopt->mds_namespace)
532− seq_printf(m, ",mds_namespace=%s", fsopt->mds_namespace);
553+ seq_show_option(m, "mds_namespace", fsopt->mds_namespace);
533554 if (fsopt->wsize)
534555 seq_printf(m, ",wsize=%d", fsopt->wsize);
535556 if (fsopt->rsize != CEPH_MAX_READ_SIZE)
@@ -679,6 +700,7 @@ struct kmem_cache *ceph_cap_cachep; · 143 unmodified lines
679700 struct kmem_cache *ceph_cap_flush_cachep;
680701 struct kmem_cache *ceph_dentry_cachep;
681702 struct kmem_cache *ceph_file_cachep;
703+struct kmem_cache *ceph_dir_file_cachep;
682704
683705 static void ceph_inode_init_once(void *foo)
684706 {
@@ -698,8 +720,7 @@ static int __init init_caches(void) · 13 unmodified lines
698720 if (!ceph_inode_cachep)
699721 return -ENOMEM;
700722
701− ceph_cap_cachep = KMEM_CACHE(ceph_cap,
702− SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD);
723+ ceph_cap_cachep = KMEM_CACHE(ceph_cap, SLAB_MEM_SPREAD);
703724 if (!ceph_cap_cachep)
704725 goto bad_cap;
705726 ceph_cap_flush_cachep = KMEM_CACHE(ceph_cap_flush,
@@ -716,6 +737,10 @@ static int __init init_caches(void) · 10 unmodified lines
716737 if (!ceph_file_cachep)
717738 goto bad_file;
718739
740+ ceph_dir_file_cachep = KMEM_CACHE(ceph_dir_file_info, SLAB_MEM_SPREAD);
741+ if (!ceph_dir_file_cachep)
742+ goto bad_dir_file;
743+
719744 error = ceph_fscache_register();
720745 if (error)
721746 goto bad_fscache;
@@ -723,6 +748,8 @@ static int __init init_caches(void) · 1 unmodified line
723748 return 0;
724749
725750 bad_fscache:
751+ kmem_cache_destroy(ceph_dir_file_cachep);
752+bad_dir_file:
726753 kmem_cache_destroy(ceph_file_cachep);
727754 bad_file:
728755 kmem_cache_destroy(ceph_dentry_cachep);
@@ -748,6 +775,7 @@ static void destroy_caches(void) · 19 unmodified lines
748775 kmem_cache_destroy(ceph_cap_flush_cachep);
749776 kmem_cache_destroy(ceph_dentry_cachep);
750777 kmem_cache_destroy(ceph_file_cachep);
778+ kmem_cache_destroy(ceph_dir_file_cachep);
751779
752780 ceph_fscache_unregister();
753781 }
fs/ceph/super.h+42−0
@@ -39,6 +39,7 @@ · 38 unmodified lines
3939 #define CEPH_MOUNT_OPT_FSCACHE (1<<10) /* use fscache */
4040 #define CEPH_MOUNT_OPT_NOPOOLPERM (1<<11) /* no pool permission check */
4141 #define CEPH_MOUNT_OPT_MOUNTWAIT (1<<12) /* mount waits if no mds is up */
42+#define CEPH_MOUNT_OPT_NOQUOTADF (1<<13) /* no root dir quota in statfs */
4243
4344 #define CEPH_MOUNT_OPT_DEFAULT CEPH_MOUNT_OPT_DCACHE
4445
@@ -310,6 +311,9 @@ struct ceph_inode_info { · 265 unmodified lines
310311 u64 i_rbytes, i_rfiles, i_rsubdirs;
311312 u64 i_files, i_subdirs;
312313
314+ /* quotas */
315+ u64 i_max_bytes, i_max_files;
316+
313317 struct rb_root i_fragtree;
314318 int i_fragtree_nsplits;
315319 struct mutex i_fragtree_mutex;
@@ -671,6 +675,10 @@ struct ceph_file_info { · 355 unmodified lines
671675
672676 spinlock_t rw_contexts_lock;
673677 struct list_head rw_contexts;
678+};
679+
680+struct ceph_dir_file_info {
681+ struct ceph_file_info file_info;
674682
675683 /* readdir: position within the dir */
676684 u32 frag;
@@ -748,6 +756,7 @@ struct ceph_readdir_cache_control { · 71 unmodified lines
748756 */
749757 struct ceph_snap_realm {
750758 u64 ino;
759+ struct inode *inode;
751760 atomic_t nref;
752761 struct rb_node node;
753762
@@ -1066,4 +1075,37 @@ extern int ceph_locks_to_pagelist(struct ceph_filelock *flocks, · 312 unmodified lines
10661075 extern int ceph_fs_debugfs_init(struct ceph_fs_client *client);
10671076 extern void ceph_fs_debugfs_cleanup(struct ceph_fs_client *client);
10681077
1078+/* quota.c */
1079+static inline bool __ceph_has_any_quota(struct ceph_inode_info *ci)
1080+{
1081+ return ci->i_max_files || ci->i_max_bytes;
1082+}
1083+
1084+extern void ceph_adjust_quota_realms_count(struct inode *inode, bool inc);
1085+
1086+static inline void __ceph_update_quota(struct ceph_inode_info *ci,
1087+ u64 max_bytes, u64 max_files)
1088+{
1089+ bool had_quota, has_quota;
1090+ had_quota = __ceph_has_any_quota(ci);
1091+ ci->i_max_bytes = max_bytes;
1092+ ci->i_max_files = max_files;
1093+ has_quota = __ceph_has_any_quota(ci);
1094+
1095+ if (had_quota != has_quota)
1096+ ceph_adjust_quota_realms_count(&ci->vfs_inode, has_quota);
1097+}
1098+
1099+extern void ceph_handle_quota(struct ceph_mds_client *mdsc,
1100+ struct ceph_mds_session *session,
1101+ struct ceph_msg *msg);
1102+extern bool ceph_quota_is_max_files_exceeded(struct inode *inode);
1103+extern bool ceph_quota_is_same_realm(struct inode *old, struct inode *new);
1104+extern bool ceph_quota_is_max_bytes_exceeded(struct inode *inode,
1105+ loff_t newlen);
1106+extern bool ceph_quota_is_max_bytes_approaching(struct inode *inode,
1107+ loff_t newlen);
1108+extern bool ceph_quota_update_statfs(struct ceph_fs_client *fsc,
1109+ struct kstatfs *buf);
1110+
10691111 #endif /* _FS_CEPH_SUPER_H */
fs/ceph/xattr.c+44−0
@@ -224,6 +224,31 @@ static size_t ceph_vxattrcb_dir_rctime(struct ceph_inode_info *ci, char *val, · 223 unmodified lines
224224 (long)ci->i_rctime.tv_nsec);
225225 }
226226
227+/* quotas */
228+
229+static bool ceph_vxattrcb_quota_exists(struct ceph_inode_info *ci)
230+{
231+ return (ci->i_max_files || ci->i_max_bytes);
232+}
233+
234+static size_t ceph_vxattrcb_quota(struct ceph_inode_info *ci, char *val,
235+ size_t size)
236+{
237+ return snprintf(val, size, "max_bytes=%llu max_files=%llu",
238+ ci->i_max_bytes, ci->i_max_files);
239+}
240+
241+static size_t ceph_vxattrcb_quota_max_bytes(struct ceph_inode_info *ci,
242+ char *val, size_t size)
243+{
244+ return snprintf(val, size, "%llu", ci->i_max_bytes);
245+}
246+
247+static size_t ceph_vxattrcb_quota_max_files(struct ceph_inode_info *ci,
248+ char *val, size_t size)
249+{
250+ return snprintf(val, size, "%llu", ci->i_max_files);
251+}
227252
228253 #define CEPH_XATTR_NAME(_type, _name) XATTR_CEPH_PREFIX #_type "." #_name
229254 #define CEPH_XATTR_NAME2(_type, _name, _name2) \
@@ -247,6 +272,15 @@ static size_t ceph_vxattrcb_dir_rctime(struct ceph_inode_info *ci, char *val, · 17 unmodified lines
247272 .hidden = true, \
248273 .exists_cb = ceph_vxattrcb_layout_exists, \
249274 }
275+#define XATTR_QUOTA_FIELD(_type, _name) \
276+ { \
277+ .name = CEPH_XATTR_NAME(_type, _name), \
278+ .name_size = sizeof(CEPH_XATTR_NAME(_type, _name)), \
279+ .getxattr_cb = ceph_vxattrcb_ ## _type ## _ ## _name, \
280+ .readonly = false, \
281+ .hidden = true, \
282+ .exists_cb = ceph_vxattrcb_quota_exists, \
283+ }
250284
251285 static struct ceph_vxattr ceph_dir_vxattrs[] = {
252286 {
@@ -270,6 +304,16 @@ static struct ceph_vxattr ceph_dir_vxattrs[] = { · 17 unmodified lines
270304 XATTR_NAME_CEPH(dir, rsubdirs),
271305 XATTR_NAME_CEPH(dir, rbytes),
272306 XATTR_NAME_CEPH(dir, rctime),
307+ {
308+ .name = "ceph.quota",
309+ .name_size = sizeof("ceph.quota"),
310+ .getxattr_cb = ceph_vxattrcb_quota,
311+ .readonly = false,
312+ .hidden = true,
313+ .exists_cb = ceph_vxattrcb_quota_exists,
314+ },
315+ XATTR_QUOTA_FIELD(quota, max_bytes),
316+ XATTR_QUOTA_FIELD(quota, max_files),
273317 { .name = NULL, 0 } /* Required table terminator */
274318 };
275319 static size_t ceph_dir_vxattrs_name_size; /* total size of all names */
include/linux/ceph/ceph_features.h+1−0
@@ -204,6 +204,7 @@ DEFINE_CEPH_FEATURE_DEPRECATED(63, 1, RESERVED_BROKEN, LUMINOUS) // client-facin · 203 unmodified lines
204204 CEPH_FEATURE_OSD_PRIMARY_AFFINITY | \
205205 CEPH_FEATURE_MSGR_KEEPALIVE2 | \
206206 CEPH_FEATURE_OSD_POOLRESEND | \
207+ CEPH_FEATURE_MDS_QUOTA | \
207208 CEPH_FEATURE_CRUSH_V4 | \
208209 CEPH_FEATURE_NEW_OSDOP_ENCODING | \
209210 CEPH_FEATURE_SERVER_JEWEL | \
include/linux/ceph/ceph_fs.h+17−0
@@ -134,6 +134,7 @@ struct ceph_dir_layout { · 133 unmodified lines
134134 #define CEPH_MSG_CLIENT_LEASE 0x311
135135 #define CEPH_MSG_CLIENT_SNAP 0x312
136136 #define CEPH_MSG_CLIENT_CAPRELEASE 0x313
137+#define CEPH_MSG_CLIENT_QUOTA 0x314
137138
138139 /* pool ops */
139140 #define CEPH_MSG_POOLOP_REPLY 48
@@ -807,4 +808,20 @@ struct ceph_mds_snap_realm { · 667 unmodified lines
807808 } __attribute__ ((packed));
808809 /* followed by my snap list, then prior parent snap list */
809810
811+/*
812+ * quotas
813+ */
814+struct ceph_mds_quota {
815+ __le64 ino; /* ino */
816+ struct ceph_timespec rctime;
817+ __le64 rbytes; /* dir stats */
818+ __le64 rfiles;
819+ __le64 rsubdirs;
820+ __u8 struct_v; /* compat */
821+ __u8 struct_compat;
822+ __le32 struct_len;
823+ __le64 max_bytes; /* quota max. bytes */
824+ __le64 max_files; /* quota max. files */
825+} __attribute__ ((packed));
826+
810827 #endif
include/linux/ceph/libceph.h+1−0
@@ -262,6 +262,7 @@ extern struct kmem_cache *ceph_cap_cachep; · 261 unmodified lines
262262 extern struct kmem_cache *ceph_cap_flush_cachep;
263263 extern struct kmem_cache *ceph_dentry_cachep;
264264 extern struct kmem_cache *ceph_file_cachep;
265+extern struct kmem_cache *ceph_dir_file_cachep;
265266
266267 /* ceph_common.c */
267268 extern bool libceph_compatible(void *data);
include/linux/ceph/messenger.h+93−8
@@ -76,6 +76,7 @@ enum ceph_msg_data_type { · 75 unmodified lines
7676 #ifdef CONFIG_BLOCK
7777 CEPH_MSG_DATA_BIO, /* data source/destination is a bio list */
7878 #endif /* CONFIG_BLOCK */
79+ CEPH_MSG_DATA_BVECS, /* data source/destination is a bio_vec array */
7980 };
8081
8182 static __inline__ bool ceph_msg_data_type_valid(enum ceph_msg_data_type type)
@@ -87,22 +88,106 @@ static __inline__ bool ceph_msg_data_type_valid(enum ceph_msg_data_type type) · 5 unmodified lines
8788 #ifdef CONFIG_BLOCK
8889 case CEPH_MSG_DATA_BIO:
8990 #endif /* CONFIG_BLOCK */
91+ case CEPH_MSG_DATA_BVECS:
9092 return true;
9193 default:
9294 return false;
9395 }
9496 }
9597
98+#ifdef CONFIG_BLOCK
99+
100+struct ceph_bio_iter {
101+ struct bio *bio;
102+ struct bvec_iter iter;
103+};
104+
105+#define __ceph_bio_iter_advance_step(it, n, STEP) do { \
106+ unsigned int __n = (n), __cur_n; \
107+ \
108+ while (__n) { \
109+ BUG_ON(!(it)->iter.bi_size); \
110+ __cur_n = min((it)->iter.bi_size, __n); \
111+ (void)(STEP); \
112+ bio_advance_iter((it)->bio, &(it)->iter, __cur_n); \
113+ if (!(it)->iter.bi_size && (it)->bio->bi_next) { \
114+ dout("__ceph_bio_iter_advance_step next bio\n"); \
115+ (it)->bio = (it)->bio->bi_next; \
116+ (it)->iter = (it)->bio->bi_iter; \
117+ } \
118+ __n -= __cur_n; \
119+ } \
120+} while (0)
121+
122+/*
123+ * Advance @it by @n bytes.
124+ */
125+#define ceph_bio_iter_advance(it, n) \
126+ __ceph_bio_iter_advance_step(it, n, 0)
127+
128+/*
129+ * Advance @it by @n bytes, executing BVEC_STEP for each bio_vec.
130+ */
131+#define ceph_bio_iter_advance_step(it, n, BVEC_STEP) \
132+ __ceph_bio_iter_advance_step(it, n, ({ \
133+ struct bio_vec bv; \
134+ struct bvec_iter __cur_iter; \
135+ \
136+ __cur_iter = (it)->iter; \
137+ __cur_iter.bi_size = __cur_n; \
138+ __bio_for_each_segment(bv, (it)->bio, __cur_iter, __cur_iter) \
139+ (void)(BVEC_STEP); \
140+ }))
141+
142+#endif /* CONFIG_BLOCK */
143+
144+struct ceph_bvec_iter {
145+ struct bio_vec *bvecs;
146+ struct bvec_iter iter;
147+};
148+
149+#define __ceph_bvec_iter_advance_step(it, n, STEP) do { \
150+ BUG_ON((n) > (it)->iter.bi_size); \
151+ (void)(STEP); \
152+ bvec_iter_advance((it)->bvecs, &(it)->iter, (n)); \
153+} while (0)
154+
155+/*
156+ * Advance @it by @n bytes.
157+ */
158+#define ceph_bvec_iter_advance(it, n) \
159+ __ceph_bvec_iter_advance_step(it, n, 0)
160+
161+/*
162+ * Advance @it by @n bytes, executing BVEC_STEP for each bio_vec.
163+ */
164+#define ceph_bvec_iter_advance_step(it, n, BVEC_STEP) \
165+ __ceph_bvec_iter_advance_step(it, n, ({ \
166+ struct bio_vec bv; \
167+ struct bvec_iter __cur_iter; \
168+ \
169+ __cur_iter = (it)->iter; \
170+ __cur_iter.bi_size = (n); \
171+ for_each_bvec(bv, (it)->bvecs, __cur_iter, __cur_iter) \
172+ (void)(BVEC_STEP); \
173+ }))
174+
175+#define ceph_bvec_iter_shorten(it, n) do { \
176+ BUG_ON((n) > (it)->iter.bi_size); \
177+ (it)->iter.bi_size = (n); \
178+} while (0)
179+
96180 struct ceph_msg_data {
97181 struct list_head links; /* ceph_msg->data */
98182 enum ceph_msg_data_type type;
99183 union {
100184 #ifdef CONFIG_BLOCK
101185 struct {
102− struct bio *bio;
103− size_t bio_length;
186+ struct ceph_bio_iter bio_pos;
187+ u32 bio_length;
104188 };
105189 #endif /* CONFIG_BLOCK */
190+ struct ceph_bvec_iter bvec_pos;
106191 struct {
107192 struct page **pages; /* NOT OWNER. */
108193 size_t length; /* total # bytes */
@@ -122,11 +207,9 @@ struct ceph_msg_data_cursor { · 13 unmodified lines
122207 bool need_crc; /* crc update needed */
123208 union {
124209 #ifdef CONFIG_BLOCK
125− struct { /* bio */
126− struct bio *bio; /* bio from list */
127− struct bvec_iter bvec_iter;
128− };
210+ struct ceph_bio_iter bio_iter;
129211 #endif /* CONFIG_BLOCK */
212+ struct bvec_iter bvec_iter;
130213 struct { /* pages */
131214 unsigned int page_offset; /* offset in page */
132215 unsigned short page_index; /* index in array */
@@ -290,9 +373,11 @@ extern void ceph_msg_data_add_pages(struct ceph_msg *msg, struct page **pages, · 157 unmodified lines
290373 extern void ceph_msg_data_add_pagelist(struct ceph_msg *msg,
291374 struct ceph_pagelist *pagelist);
292375 #ifdef CONFIG_BLOCK
293−extern void ceph_msg_data_add_bio(struct ceph_msg *msg, struct bio *bio,
294− size_t length);
376+void ceph_msg_data_add_bio(struct ceph_msg *msg, struct ceph_bio_iter *bio_pos,
377+ u32 length);
295378 #endif /* CONFIG_BLOCK */
379+void ceph_msg_data_add_bvecs(struct ceph_msg *msg,
380+ struct ceph_bvec_iter *bvec_pos);
296381
297382 extern struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags,
298383 bool can_fail);
include/linux/ceph/osd_client.h+14−5
@@ -57,6 +57,7 @@ enum ceph_osd_data_type { · 56 unmodified lines
5757 #ifdef CONFIG_BLOCK
5858 CEPH_OSD_DATA_TYPE_BIO,
5959 #endif /* CONFIG_BLOCK */
60+ CEPH_OSD_DATA_TYPE_BVECS,
6061 };
6162
6263 struct ceph_osd_data {
@@ -72,10 +73,11 @@ struct ceph_osd_data { · 9 unmodified lines
7273 struct ceph_pagelist *pagelist;
7374 #ifdef CONFIG_BLOCK
7475 struct {
75− struct bio *bio; /* list of bios */
76− size_t bio_length; /* total in list */
76+ struct ceph_bio_iter bio_pos;
77+ u32 bio_length;
7778 };
7879 #endif /* CONFIG_BLOCK */
80+ struct ceph_bvec_iter bvec_pos;
7981 };
8082 };
8183
@@ -405,10 +407,14 @@ extern void osd_req_op_extent_osd_data_pagelist(struct ceph_osd_request *, · 323 unmodified lines
405407 unsigned int which,
406408 struct ceph_pagelist *pagelist);
407409 #ifdef CONFIG_BLOCK
408−extern void osd_req_op_extent_osd_data_bio(struct ceph_osd_request *,
409− unsigned int which,
410− struct bio *bio, size_t bio_length);
410+void osd_req_op_extent_osd_data_bio(struct ceph_osd_request *osd_req,
411+ unsigned int which,
412+ struct ceph_bio_iter *bio_pos,
413+ u32 bio_length);
411414 #endif /* CONFIG_BLOCK */
415+void osd_req_op_extent_osd_data_bvec_pos(struct ceph_osd_request *osd_req,
416+ unsigned int which,
417+ struct ceph_bvec_iter *bvec_pos);
412418
413419 extern void osd_req_op_cls_request_data_pagelist(struct ceph_osd_request *,
414420 unsigned int which,
@@ -418,6 +424,9 @@ extern void osd_req_op_cls_request_data_pages(struct ceph_osd_request *, · 3 unmodified lines
418424 struct page **pages, u64 length,
419425 u32 alignment, bool pages_from_pool,
420426 bool own_pages);
427+void osd_req_op_cls_request_data_bvecs(struct ceph_osd_request *osd_req,
428+ unsigned int which,
429+ struct bio_vec *bvecs, u32 bytes);
421430 extern void osd_req_op_cls_response_data_pages(struct ceph_osd_request *,
422431 unsigned int which,
423432 struct page **pages, u64 length,
include/linux/ceph/osdmap.h+0−6
@@ -5,7 +5,6 @@ · 4 unmodified lines
55 #include <linux/rbtree.h>
66 #include <linux/ceph/types.h>
77 #include <linux/ceph/decode.h>
8−#include <linux/ceph/ceph_fs.h>
98 #include <linux/crush/crush.h>
109
1110 /*
@@ -280,11 +279,6 @@ bool ceph_osds_changed(const struct ceph_osds *old_acting, · 268 unmodified lines
280279 const struct ceph_osds *new_acting,
281280 bool any_change);
282281
283−/* calculate mapping of a file extent to an object */
284−extern int ceph_calc_file_object_mapping(struct ceph_file_layout *layout,
285− u64 off, u64 len,
286− u64 *bno, u64 *oxoff, u64 *oxlen);
287−
288282 int __ceph_object_locator_to_pg(struct ceph_pg_pool_info *pi,
289283 const struct ceph_object_id *oid,
290284 const struct ceph_object_locator *oloc,
include/linux/ceph/striper.h+69−0
@@ -0,0 +1,69 @@
1+/* SPDX-License-Identifier: GPL-2.0 */
2+#ifndef _LINUX_CEPH_STRIPER_H
3+#define _LINUX_CEPH_STRIPER_H
4+
5+#include <linux/list.h>
6+#include <linux/types.h>
7+
8+struct ceph_file_layout;
9+
10+void ceph_calc_file_object_mapping(struct ceph_file_layout *l,
11+ u64 off, u64 len,
12+ u64 *objno, u64 *objoff, u32 *xlen);
13+
14+struct ceph_object_extent {
15+ struct list_head oe_item;
16+ u64 oe_objno;
17+ u64 oe_off;
18+ u64 oe_len;
19+};
20+
21+static inline void ceph_object_extent_init(struct ceph_object_extent *ex)
22+{
23+ INIT_LIST_HEAD(&ex->oe_item);
24+}
25+
26+/*
27+ * Called for each mapped stripe unit.
28+ *
29+ * @bytes: number of bytes mapped, i.e. the minimum of the full length
30+ * requested (file extent length) or the remainder of the stripe
31+ * unit within an object
32+ */
33+typedef void (*ceph_object_extent_fn_t)(struct ceph_object_extent *ex,
34+ u32 bytes, void *arg);
35+
36+int ceph_file_to_extents(struct ceph_file_layout *l, u64 off, u64 len,
37+ struct list_head *object_extents,
38+ struct ceph_object_extent *alloc_fn(void *arg),
39+ void *alloc_arg,
40+ ceph_object_extent_fn_t action_fn,
41+ void *action_arg);
42+int ceph_iterate_extents(struct ceph_file_layout *l, u64 off, u64 len,
43+ struct list_head *object_extents,
44+ ceph_object_extent_fn_t action_fn,
45+ void *action_arg);
46+
47+struct ceph_file_extent {
48+ u64 fe_off;
49+ u64 fe_len;
50+};
51+
52+static inline u64 ceph_file_extents_bytes(struct ceph_file_extent *file_extents,
53+ u32 num_file_extents)
54+{
55+ u64 bytes = 0;
56+ u32 i;
57+
58+ for (i = 0; i < num_file_extents; i++)
59+ bytes += file_extents[i].fe_len;
60+
61+ return bytes;
62+}
63+
64+int ceph_extent_to_file(struct ceph_file_layout *l,
65+ u64 objno, u64 objoff, u64 objlen,
66+ struct ceph_file_extent **file_extents,
67+ u32 *num_file_extents);
68+
69+#endif
net/ceph/Makefile+1−0
@@ -8,6 +8,7 @@ libceph-y := ceph_common.o messenger.o msgpool.o buffer.o pagelist.o \ · 7 unmodified lines
88 mon_client.o \
99 cls_lock_client.o \
1010 osd_client.o osdmap.o crush/crush.o crush/mapper.o crush/hash.o \
11+ striper.o \
1112 debugfs.o \
1213 auth.o auth_none.o \
1314 crypto.o armor.o \
net/ceph/ceph_common.c+7−1
@@ -72,6 +72,7 @@ const char *ceph_msg_type_name(int type) · 71 unmodified lines
7272 case CEPH_MSG_MON_GET_VERSION: return "mon_get_version";
7373 case CEPH_MSG_MON_GET_VERSION_REPLY: return "mon_get_version_reply";
7474 case CEPH_MSG_MDS_MAP: return "mds_map";
75+ case CEPH_MSG_FS_MAP_USER: return "fs_map_user";
7576 case CEPH_MSG_CLIENT_SESSION: return "client_session";
7677 case CEPH_MSG_CLIENT_RECONNECT: return "client_reconnect";
7778 case CEPH_MSG_CLIENT_REQUEST: return "client_request";
@@ -79,8 +80,13 @@ const char *ceph_msg_type_name(int type) · 1 unmodified line
7980 case CEPH_MSG_CLIENT_REPLY: return "client_reply";
8081 case CEPH_MSG_CLIENT_CAPS: return "client_caps";
8182 case CEPH_MSG_CLIENT_CAPRELEASE: return "client_cap_release";
83+ case CEPH_MSG_CLIENT_QUOTA: return "client_quota";
8284 case CEPH_MSG_CLIENT_SNAP: return "client_snap";
8385 case CEPH_MSG_CLIENT_LEASE: return "client_lease";
86+ case CEPH_MSG_POOLOP_REPLY: return "poolop_reply";
87+ case CEPH_MSG_POOLOP: return "poolop";
88+ case CEPH_MSG_MON_COMMAND: return "mon_command";
89+ case CEPH_MSG_MON_COMMAND_ACK: return "mon_command_ack";
8490 case CEPH_MSG_OSD_MAP: return "osd_map";
8591 case CEPH_MSG_OSD_OP: return "osd_op";
8692 case CEPH_MSG_OSD_OPREPLY: return "osd_opreply";
@@ -217,7 +223,7 @@ static int parse_fsid(const char *str, struct ceph_fsid *fsid) · 130 unmodified lines
217223
218224 if (i == 16)
219225 err = 0;
220− dout("parse_fsid ret %d got fsid %pU", err, fsid);
226+ dout("parse_fsid ret %d got fsid %pU\n", err, fsid);
221227 return err;
222228 }
223229
net/ceph/crypto.c+4−2
@@ -347,10 +347,12 @@ struct key_type key_type_ceph = { · 346 unmodified lines
347347 .destroy = ceph_key_destroy,
348348 };
349349
350−int ceph_crypto_init(void) {
350+int __init ceph_crypto_init(void)
351+{
351352 return register_key_type(&key_type_ceph);
352353 }
353354
354−void ceph_crypto_shutdown(void) {
355+void ceph_crypto_shutdown(void)
356+{
355357 unregister_key_type(&key_type_ceph);
356358 }
net/ceph/debugfs.c+7−10
@@ -389,7 +389,7 @@ CEPH_DEFINE_SHOW_FUNC(monc_show) · 388 unmodified lines
389389 CEPH_DEFINE_SHOW_FUNC(osdc_show)
390390 CEPH_DEFINE_SHOW_FUNC(client_options_show)
391391
392−int ceph_debugfs_init(void)
392+int __init ceph_debugfs_init(void)
393393 {
394394 ceph_debugfs_dir = debugfs_create_dir("ceph", NULL);
395395 if (!ceph_debugfs_dir)
@@ -418,7 +418,7 @@ int ceph_debugfs_client_init(struct ceph_client *client) · 22 unmodified lines
418418 goto out;
419419
420420 client->monc.debugfs_file = debugfs_create_file("monc",
421− 0600,
421+ 0400,
422422 client->debugfs_dir,
423423 client,
424424 &monc_show_fops);
@@ -426,7 +426,7 @@ int ceph_debugfs_client_init(struct ceph_client *client) · 1 unmodified line
426426 goto out;
427427
428428 client->osdc.debugfs_file = debugfs_create_file("osdc",
429− 0600,
429+ 0400,
430430 client->debugfs_dir,
431431 client,
432432 &osdc_show_fops);
@@ -434,7 +434,7 @@ int ceph_debugfs_client_init(struct ceph_client *client) · 1 unmodified line
434434 goto out;
435435
436436 client->debugfs_monmap = debugfs_create_file("monmap",
437− 0600,
437+ 0400,
438438 client->debugfs_dir,
439439 client,
440440 &monmap_show_fops);
@@ -442,7 +442,7 @@ int ceph_debugfs_client_init(struct ceph_client *client) · 1 unmodified line
442442 goto out;
443443
444444 client->debugfs_osdmap = debugfs_create_file("osdmap",
445− 0600,
445+ 0400,
446446 client->debugfs_dir,
447447 client,
448448 &osdmap_show_fops);
@@ -450,7 +450,7 @@ int ceph_debugfs_client_init(struct ceph_client *client) · 1 unmodified line
450450 goto out;
451451
452452 client->debugfs_options = debugfs_create_file("client_options",
453− 0600,
453+ 0400,
454454 client->debugfs_dir,
455455 client,
456456 &client_options_show_fops);
@@ -477,7 +477,7 @@ void ceph_debugfs_client_cleanup(struct ceph_client *client) · 20 unmodified lines
477477
478478 #else /* CONFIG_DEBUG_FS */
479479
480−int ceph_debugfs_init(void)
480+int __init ceph_debugfs_init(void)
481481 {
482482 return 0;
483483 }
@@ -496,6 +496,3 @@ void ceph_debugfs_client_cleanup(struct ceph_client *client) · 12 unmodified lines
496496 }
497497
498498 #endif /* CONFIG_DEBUG_FS */
499−
500−EXPORT_SYMBOL(ceph_debugfs_init);
501−EXPORT_SYMBOL(ceph_debugfs_cleanup);
net/ceph/messenger.c+119−69
@@ -277,7 +277,7 @@ static void _ceph_msgr_exit(void) · 276 unmodified lines
277277 ceph_msgr_slab_exit();
278278 }
279279
280−int ceph_msgr_init(void)
280+int __init ceph_msgr_init(void)
281281 {
282282 if (ceph_msgr_slab_init())
283283 return -ENOMEM;
@@ -299,7 +299,6 @@ int ceph_msgr_init(void) · 15 unmodified lines
299299
300300 return -ENOMEM;
301301 }
302−EXPORT_SYMBOL(ceph_msgr_init);
303302
304303 void ceph_msgr_exit(void)
305304 {
@@ -307,7 +306,6 @@ void ceph_msgr_exit(void) · 1 unmodified line
307306
308307 _ceph_msgr_exit();
309308 }
310−EXPORT_SYMBOL(ceph_msgr_exit);
311309
312310 void ceph_msgr_flush(void)
313311 {
@@ -839,93 +837,112 @@ static void ceph_msg_data_bio_cursor_init(struct ceph_msg_data_cursor *cursor, · 525 unmodified lines
839837 size_t length)
840838 {
841839 struct ceph_msg_data *data = cursor->data;
842− struct bio *bio;
840+ struct ceph_bio_iter *it = &cursor->bio_iter;
843841
844− BUG_ON(data->type != CEPH_MSG_DATA_BIO);
842+ cursor->resid = min_t(size_t, length, data->bio_length);
843+ *it = data->bio_pos;
844+ if (cursor->resid < it->iter.bi_size)
845+ it->iter.bi_size = cursor->resid;
845846
846− bio = data->bio;
847− BUG_ON(!bio);
848−
849− cursor->resid = min(length, data->bio_length);
850− cursor->bio = bio;
851− cursor->bvec_iter = bio->bi_iter;
852− cursor->last_piece =
853− cursor->resid <= bio_iter_len(bio, cursor->bvec_iter);
847+ BUG_ON(cursor->resid < bio_iter_len(it->bio, it->iter));
848+ cursor->last_piece = cursor->resid == bio_iter_len(it->bio, it->iter);
854849 }
855850
856851 static struct page *ceph_msg_data_bio_next(struct ceph_msg_data_cursor *cursor,
857852 size_t *page_offset,
858853 size_t *length)
859854 {
860− struct ceph_msg_data *data = cursor->data;
861− struct bio *bio;
862− struct bio_vec bio_vec;
863−
864− BUG_ON(data->type != CEPH_MSG_DATA_BIO);
865−
866− bio = cursor->bio;
867− BUG_ON(!bio);
868−
869− bio_vec = bio_iter_iovec(bio, cursor->bvec_iter);
870−
871− *page_offset = (size_t) bio_vec.bv_offset;
872− BUG_ON(*page_offset >= PAGE_SIZE);
873− if (cursor->last_piece) /* pagelist offset is always 0 */
874− *length = cursor->resid;
875− else
876− *length = (size_t) bio_vec.bv_len;
877− BUG_ON(*length > cursor->resid);
878− BUG_ON(*page_offset + *length > PAGE_SIZE);
855+ struct bio_vec bv = bio_iter_iovec(cursor->bio_iter.bio,
856+ cursor->bio_iter.iter);
879857
880− return bio_vec.bv_page;
858+ *page_offset = bv.bv_offset;
859+ *length = bv.bv_len;
860+ return bv.bv_page;
881861 }
882862
883863 static bool ceph_msg_data_bio_advance(struct ceph_msg_data_cursor *cursor,
884864 size_t bytes)
885865 {
886− struct bio *bio;
887− struct bio_vec bio_vec;
866+ struct ceph_bio_iter *it = &cursor->bio_iter;
888867
889− BUG_ON(cursor->data->type != CEPH_MSG_DATA_BIO);
868+ BUG_ON(bytes > cursor->resid);
869+ BUG_ON(bytes > bio_iter_len(it->bio, it->iter));
870+ cursor->resid -= bytes;
871+ bio_advance_iter(it->bio, &it->iter, bytes);
890872
891− bio = cursor->bio;
892− BUG_ON(!bio);
873+ if (!cursor->resid) {
874+ BUG_ON(!cursor->last_piece);
875+ return false; /* no more data */
876+ }
893877
894− bio_vec = bio_iter_iovec(bio, cursor->bvec_iter);
878+ if (!bytes || (it->iter.bi_size && it->iter.bi_bvec_done))
879+ return false; /* more bytes to process in this segment */
895880
896− /* Advance the cursor offset */
881+ if (!it->iter.bi_size) {
882+ it->bio = it->bio->bi_next;
883+ it->iter = it->bio->bi_iter;
884+ if (cursor->resid < it->iter.bi_size)
885+ it->iter.bi_size = cursor->resid;
886+ }
897887
898− BUG_ON(cursor->resid < bytes);
899− cursor->resid -= bytes;
888+ BUG_ON(cursor->last_piece);
889+ BUG_ON(cursor->resid < bio_iter_len(it->bio, it->iter));
890+ cursor->last_piece = cursor->resid == bio_iter_len(it->bio, it->iter);
891+ return true;
892+}
893+#endif /* CONFIG_BLOCK */
900894
901− bio_advance_iter(bio, &cursor->bvec_iter, bytes);
895+static void ceph_msg_data_bvecs_cursor_init(struct ceph_msg_data_cursor *cursor,
896+ size_t length)
897+{
898+ struct ceph_msg_data *data = cursor->data;
899+ struct bio_vec *bvecs = data->bvec_pos.bvecs;
902900
903− if (bytes < bio_vec.bv_len)
904− return false; /* more bytes to process in this segment */
901+ cursor->resid = min_t(size_t, length, data->bvec_pos.iter.bi_size);
902+ cursor->bvec_iter = data->bvec_pos.iter;
903+ cursor->bvec_iter.bi_size = cursor->resid;
905904
906− /* Move on to the next segment, and possibly the next bio */
905+ BUG_ON(cursor->resid < bvec_iter_len(bvecs, cursor->bvec_iter));
906+ cursor->last_piece =
907+ cursor->resid == bvec_iter_len(bvecs, cursor->bvec_iter);
908+}
907909
908− if (!cursor->bvec_iter.bi_size) {
909− bio = bio->bi_next;
910− cursor->bio = bio;
911− if (bio)
912− cursor->bvec_iter = bio->bi_iter;
913− else
914− memset(&cursor->bvec_iter, 0,
915− sizeof(cursor->bvec_iter));
916− }
910+static struct page *ceph_msg_data_bvecs_next(struct ceph_msg_data_cursor *cursor,
911+ size_t *page_offset,
912+ size_t *length)
913+{
914+ struct bio_vec bv = bvec_iter_bvec(cursor->data->bvec_pos.bvecs,
915+ cursor->bvec_iter);
916+
917+ *page_offset = bv.bv_offset;
918+ *length = bv.bv_len;
919+ return bv.bv_page;
920+}
921+
922+static bool ceph_msg_data_bvecs_advance(struct ceph_msg_data_cursor *cursor,
923+ size_t bytes)
924+{
925+ struct bio_vec *bvecs = cursor->data->bvec_pos.bvecs;
926+
927+ BUG_ON(bytes > cursor->resid);
928+ BUG_ON(bytes > bvec_iter_len(bvecs, cursor->bvec_iter));
929+ cursor->resid -= bytes;
930+ bvec_iter_advance(bvecs, &cursor->bvec_iter, bytes);
917931
918− if (!cursor->last_piece) {
919− BUG_ON(!cursor->resid);
920− BUG_ON(!bio);
921− /* A short read is OK, so use <= rather than == */
922− if (cursor->resid <= bio_iter_len(bio, cursor->bvec_iter))
923− cursor->last_piece = true;
932+ if (!cursor->resid) {
933+ BUG_ON(!cursor->last_piece);
934+ return false; /* no more data */
924935 }
925936
937+ if (!bytes || cursor->bvec_iter.bi_bvec_done)
938+ return false; /* more bytes to process in this segment */
939+
940+ BUG_ON(cursor->last_piece);
941+ BUG_ON(cursor->resid < bvec_iter_len(bvecs, cursor->bvec_iter));
942+ cursor->last_piece =
943+ cursor->resid == bvec_iter_len(bvecs, cursor->bvec_iter);
926944 return true;
927945 }
928−#endif /* CONFIG_BLOCK */
929946
930947 /*
931948 * For a page array, a piece comes from the first page in the array
@@ -1110,6 +1127,9 @@ static void __ceph_msg_data_cursor_init(struct ceph_msg_data_cursor *cursor) · 178 unmodified lines
11101127 ceph_msg_data_bio_cursor_init(cursor, length);
11111128 break;
11121129 #endif /* CONFIG_BLOCK */
1130+ case CEPH_MSG_DATA_BVECS:
1131+ ceph_msg_data_bvecs_cursor_init(cursor, length);
1132+ break;
11131133 case CEPH_MSG_DATA_NONE:
11141134 default:
11151135 /* BUG(); */
@@ -1158,14 +1178,19 @@ static struct page *ceph_msg_data_next(struct ceph_msg_data_cursor *cursor, · 42 unmodified lines
11581178 page = ceph_msg_data_bio_next(cursor, page_offset, length);
11591179 break;
11601180 #endif /* CONFIG_BLOCK */
1181+ case CEPH_MSG_DATA_BVECS:
1182+ page = ceph_msg_data_bvecs_next(cursor, page_offset, length);
1183+ break;
11611184 case CEPH_MSG_DATA_NONE:
11621185 default:
11631186 page = NULL;
11641187 break;
11651188 }
1189+
11661190 BUG_ON(!page);
11671191 BUG_ON(*page_offset + *length > PAGE_SIZE);
11681192 BUG_ON(!*length);
1193+ BUG_ON(*length > cursor->resid);
11691194 if (last_piece)
11701195 *last_piece = cursor->last_piece;
11711196
@@ -1194,6 +1219,9 @@ static void ceph_msg_data_advance(struct ceph_msg_data_cursor *cursor, · 22 unmodified lines
11941219 new_piece = ceph_msg_data_bio_advance(cursor, bytes);
11951220 break;
11961221 #endif /* CONFIG_BLOCK */
1222+ case CEPH_MSG_DATA_BVECS:
1223+ new_piece = ceph_msg_data_bvecs_advance(cursor, bytes);
1224+ break;
11971225 case CEPH_MSG_DATA_NONE:
11981226 default:
11991227 BUG();
@@ -1575,13 +1603,18 @@ static int write_partial_message_data(struct ceph_connection *con) · 375 unmodified lines
15751603 * been revoked, so use the zero page.
15761604 */
15771605 crc = do_datacrc ? le32_to_cpu(msg->footer.data_crc) : 0;
1578− while (cursor->resid) {
1606+ while (cursor->total_resid) {
15791607 struct page *page;
15801608 size_t page_offset;
15811609 size_t length;
15821610 bool last_piece;
15831611 int ret;
15841612
1613+ if (!cursor->resid) {
1614+ ceph_msg_data_advance(cursor, 0);
1615+ continue;
1616+ }
1617+
15851618 page = ceph_msg_data_next(cursor, &page_offset, &length,
15861619 &last_piece);
15871620 ret = ceph_tcp_sendpage(con->sock, page, page_offset,
@@ -2297,7 +2330,12 @@ static int read_partial_msg_data(struct ceph_connection *con) · 709 unmodified lines
22972330
22982331 if (do_datacrc)
22992332 crc = con->in_data_crc;
2300− while (cursor->resid) {
2333+ while (cursor->total_resid) {
2334+ if (!cursor->resid) {
2335+ ceph_msg_data_advance(cursor, 0);
2336+ continue;
2337+ }
2338+
23012339 page = ceph_msg_data_next(cursor, &page_offset, &length, NULL);
23022340 ret = ceph_tcp_recvpage(con->sock, page, page_offset, length);
23032341 if (ret <= 0) {
@@ -3262,16 +3300,14 @@ void ceph_msg_data_add_pagelist(struct ceph_msg *msg, · 958 unmodified lines
32623300 EXPORT_SYMBOL(ceph_msg_data_add_pagelist);
32633301
32643302 #ifdef CONFIG_BLOCK
3265−void ceph_msg_data_add_bio(struct ceph_msg *msg, struct bio *bio,
3266− size_t length)
3303+void ceph_msg_data_add_bio(struct ceph_msg *msg, struct ceph_bio_iter *bio_pos,
3304+ u32 length)
32673305 {
32683306 struct ceph_msg_data *data;
32693307
3270− BUG_ON(!bio);
3271−
32723308 data = ceph_msg_data_create(CEPH_MSG_DATA_BIO);
32733309 BUG_ON(!data);
3274− data->bio = bio;
3310+ data->bio_pos = *bio_pos;
32753311 data->bio_length = length;
32763312
32773313 list_add_tail(&data->links, &msg->data);
@@ -3280,6 +3316,20 @@ void ceph_msg_data_add_bio(struct ceph_msg *msg, struct bio *bio, · 2 unmodified lines
32803316 EXPORT_SYMBOL(ceph_msg_data_add_bio);
32813317 #endif /* CONFIG_BLOCK */
32823318
3319+void ceph_msg_data_add_bvecs(struct ceph_msg *msg,
3320+ struct ceph_bvec_iter *bvec_pos)
3321+{
3322+ struct ceph_msg_data *data;
3323+
3324+ data = ceph_msg_data_create(CEPH_MSG_DATA_BVECS);
3325+ BUG_ON(!data);
3326+ data->bvec_pos = *bvec_pos;
3327+
3328+ list_add_tail(&data->links, &msg->data);
3329+ msg->data_length += bvec_pos->iter.bi_size;
3330+}
3331+EXPORT_SYMBOL(ceph_msg_data_add_bvecs);
3332+
32833333 /*
32843334 * construct a new message with given type, size
32853335 * the new msg has a ref count of 1.
net/ceph/mon_client.c+1−1
@@ -60,7 +60,7 @@ struct ceph_monmap *ceph_monmap_decode(void *p, void *end) · 59 unmodified lines
6060 num_mon = ceph_decode_32(&p);
6161 ceph_decode_need(&p, end, num_mon*sizeof(m->mon_inst[0]), bad);
6262
63− if (num_mon >= CEPH_MAX_MON)
63+ if (num_mon > CEPH_MAX_MON)
6464 goto bad;
6565 m = kmalloc(sizeof(*m) + sizeof(m->mon_inst[0])*num_mon, GFP_NOFS);
6666 if (m == NULL)
net/ceph/osd_client.c+53−14
@@ -20,6 +20,7 @@ · 19 unmodified lines
2020 #include <linux/ceph/decode.h>
2121 #include <linux/ceph/auth.h>
2222 #include <linux/ceph/pagelist.h>
23+#include <linux/ceph/striper.h>
2324
2425 #define OSD_OPREPLY_FRONT_LEN 512
2526
@@ -103,13 +104,12 @@ static int calc_layout(struct ceph_file_layout *layout, u64 off, u64 *plen, · 77 unmodified lines
103104 u64 *objnum, u64 *objoff, u64 *objlen)
104105 {
105106 u64 orig_len = *plen;
106− int r;
107+ u32 xlen;
107108
108109 /* object extent? */
109− r = ceph_calc_file_object_mapping(layout, off, orig_len, objnum,
110− objoff, objlen);
111− if (r < 0)
112− return r;
110+ ceph_calc_file_object_mapping(layout, off, orig_len, objnum,
111+ objoff, &xlen);
112+ *objlen = xlen;
113113 if (*objlen < orig_len) {
114114 *plen = *objlen;
115115 dout(" skipping last %llu, final file extent %llu~%llu\n",
@@ -117,7 +117,6 @@ static int calc_layout(struct ceph_file_layout *layout, u64 off, u64 *plen, · 1 unmodified line
117117 }
118118
119119 dout("calc_layout objnum=%llx %llu~%llu\n", *objnum, *objoff, *objlen);
120−
121120 return 0;
122121 }
123122
@@ -148,14 +147,22 @@ static void ceph_osd_data_pagelist_init(struct ceph_osd_data *osd_data, · 24 unmodified lines
148147
149148 #ifdef CONFIG_BLOCK
150149 static void ceph_osd_data_bio_init(struct ceph_osd_data *osd_data,
151− struct bio *bio, size_t bio_length)
150+ struct ceph_bio_iter *bio_pos,
151+ u32 bio_length)
152152 {
153153 osd_data->type = CEPH_OSD_DATA_TYPE_BIO;
154− osd_data->bio = bio;
154+ osd_data->bio_pos = *bio_pos;
155155 osd_data->bio_length = bio_length;
156156 }
157157 #endif /* CONFIG_BLOCK */
158158
159+static void ceph_osd_data_bvecs_init(struct ceph_osd_data *osd_data,
160+ struct ceph_bvec_iter *bvec_pos)
161+{
162+ osd_data->type = CEPH_OSD_DATA_TYPE_BVECS;
163+ osd_data->bvec_pos = *bvec_pos;
164+}
165+
159166 #define osd_req_op_data(oreq, whch, typ, fld) \
160167 ({ \
161168 struct ceph_osd_request *__oreq = (oreq); \
@@ -218,16 +225,29 @@ EXPORT_SYMBOL(osd_req_op_extent_osd_data_pagelist); · 56 unmodified lines
218225
219226 #ifdef CONFIG_BLOCK
220227 void osd_req_op_extent_osd_data_bio(struct ceph_osd_request *osd_req,
221− unsigned int which, struct bio *bio, size_t bio_length)
228+ unsigned int which,
229+ struct ceph_bio_iter *bio_pos,
230+ u32 bio_length)
222231 {
223232 struct ceph_osd_data *osd_data;
224233
225234 osd_data = osd_req_op_data(osd_req, which, extent, osd_data);
226− ceph_osd_data_bio_init(osd_data, bio, bio_length);
235+ ceph_osd_data_bio_init(osd_data, bio_pos, bio_length);
227236 }
228237 EXPORT_SYMBOL(osd_req_op_extent_osd_data_bio);
229238 #endif /* CONFIG_BLOCK */
230239
240+void osd_req_op_extent_osd_data_bvec_pos(struct ceph_osd_request *osd_req,
241+ unsigned int which,
242+ struct ceph_bvec_iter *bvec_pos)
243+{
244+ struct ceph_osd_data *osd_data;
245+
246+ osd_data = osd_req_op_data(osd_req, which, extent, osd_data);
247+ ceph_osd_data_bvecs_init(osd_data, bvec_pos);
248+}
249+EXPORT_SYMBOL(osd_req_op_extent_osd_data_bvec_pos);
250+
231251 static void osd_req_op_cls_request_info_pagelist(
232252 struct ceph_osd_request *osd_req,
233253 unsigned int which, struct ceph_pagelist *pagelist)
@@ -265,6 +285,23 @@ void osd_req_op_cls_request_data_pages(struct ceph_osd_request *osd_req, · 31 unmodified lines
265285 }
266286 EXPORT_SYMBOL(osd_req_op_cls_request_data_pages);
267287
288+void osd_req_op_cls_request_data_bvecs(struct ceph_osd_request *osd_req,
289+ unsigned int which,
290+ struct bio_vec *bvecs, u32 bytes)
291+{
292+ struct ceph_osd_data *osd_data;
293+ struct ceph_bvec_iter it = {
294+ .bvecs = bvecs,
295+ .iter = { .bi_size = bytes },
296+ };
297+
298+ osd_data = osd_req_op_data(osd_req, which, cls, request_data);
299+ ceph_osd_data_bvecs_init(osd_data, &it);
300+ osd_req->r_ops[which].cls.indata_len += bytes;
301+ osd_req->r_ops[which].indata_len += bytes;
302+}
303+EXPORT_SYMBOL(osd_req_op_cls_request_data_bvecs);
304+
268305 void osd_req_op_cls_response_data_pages(struct ceph_osd_request *osd_req,
269306 unsigned int which, struct page **pages, u64 length,
270307 u32 alignment, bool pages_from_pool, bool own_pages)
@@ -290,6 +327,8 @@ static u64 ceph_osd_data_length(struct ceph_osd_data *osd_data) · 19 unmodified lines
290327 case CEPH_OSD_DATA_TYPE_BIO:
291328 return (u64)osd_data->bio_length;
292329 #endif /* CONFIG_BLOCK */
330+ case CEPH_OSD_DATA_TYPE_BVECS:
331+ return osd_data->bvec_pos.iter.bi_size;
293332 default:
294333 WARN(true, "unrecognized data type %d\n", (int)osd_data->type);
295334 return 0;
@@ -828,8 +867,10 @@ static void ceph_osdc_msg_data_add(struct ceph_msg *msg, · 532 unmodified lines
828867 ceph_msg_data_add_pagelist(msg, osd_data->pagelist);
829868 #ifdef CONFIG_BLOCK
830869 } else if (osd_data->type == CEPH_OSD_DATA_TYPE_BIO) {
831− ceph_msg_data_add_bio(msg, osd_data->bio, length);
870+ ceph_msg_data_add_bio(msg, &osd_data->bio_pos, length);
832871 #endif
872+ } else if (osd_data->type == CEPH_OSD_DATA_TYPE_BVECS) {
873+ ceph_msg_data_add_bvecs(msg, &osd_data->bvec_pos);
833874 } else {
834875 BUG_ON(osd_data->type != CEPH_OSD_DATA_TYPE_NONE);
835876 }
@@ -5065,7 +5106,7 @@ int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino, · 4229 unmodified lines
50655106 }
50665107 EXPORT_SYMBOL(ceph_osdc_writepages);
50675108
5068−int ceph_osdc_setup(void)
5109+int __init ceph_osdc_setup(void)
50695110 {
50705111 size_t size = sizeof(struct ceph_osd_request) +
50715112 CEPH_OSD_SLAB_OPS * sizeof(struct ceph_osd_req_op);
@@ -5076,7 +5117,6 @@ int ceph_osdc_setup(void) · 4 unmodified lines
50765117
50775118 return ceph_osd_request_cache ? 0 : -ENOMEM;
50785119 }
5079−EXPORT_SYMBOL(ceph_osdc_setup);
50805120
50815121 void ceph_osdc_cleanup(void)
50825122 {
@@ -5084,7 +5124,6 @@ void ceph_osdc_cleanup(void) · 1 unmodified line
50845124 kmem_cache_destroy(ceph_osd_request_cache);
50855125 ceph_osd_request_cache = NULL;
50865126 }
5087−EXPORT_SYMBOL(ceph_osdc_cleanup);
50885127
50895128 /*
50905129 * handle incoming message
net/ceph/osdmap.c+0−71
@@ -4,7 +4,6 @@ · 3 unmodified lines
44
55 #include <linux/module.h>
66 #include <linux/slab.h>
7−#include <asm/div64.h>
87
98 #include <linux/ceph/libceph.h>
109 #include <linux/ceph/osdmap.h>
@@ -2140,76 +2139,6 @@ bool ceph_osds_changed(const struct ceph_osds *old_acting, · 2129 unmodified lines
21402139 return false;
21412140 }
21422141
2143−/*
2144− * calculate file layout from given offset, length.
2145− * fill in correct oid, logical length, and object extent
2146− * offset, length.
2147− *
2148− * for now, we write only a single su, until we can
2149− * pass a stride back to the caller.
2150− */
2151−int ceph_calc_file_object_mapping(struct ceph_file_layout *layout,
2152− u64 off, u64 len,
2153− u64 *ono,
2154− u64 *oxoff, u64 *oxlen)
2155−{
2156− u32 osize = layout->object_size;
2157− u32 su = layout->stripe_unit;
2158− u32 sc = layout->stripe_count;
2159− u32 bl, stripeno, stripepos, objsetno;
2160− u32 su_per_object;
2161− u64 t, su_offset;
2162−
2163− dout("mapping %llu~%llu osize %u fl_su %u\n", off, len,
2164− osize, su);
2165− if (su == 0 || sc == 0)
2166− goto invalid;
2167− su_per_object = osize / su;
2168− if (su_per_object == 0)
2169− goto invalid;
2170− dout("osize %u / su %u = su_per_object %u\n", osize, su,
2171− su_per_object);
2172−
2173− if ((su & ~PAGE_MASK) != 0)
2174− goto invalid;
2175−
2176− /* bl = *off / su; */
2177− t = off;
2178− do_div(t, su);
2179− bl = t;
2180− dout("off %llu / su %u = bl %u\n", off, su, bl);
2181−
2182− stripeno = bl / sc;
2183− stripepos = bl % sc;
2184− objsetno = stripeno / su_per_object;
2185−
2186− *ono = objsetno * sc + stripepos;
2187− dout("objset %u * sc %u = ono %u\n", objsetno, sc, (unsigned int)*ono);
2188−
2189− /* *oxoff = *off % layout->fl_stripe_unit; # offset in su */
2190− t = off;
2191− su_offset = do_div(t, su);
2192− *oxoff = su_offset + (stripeno % su_per_object) * su;
2193−
2194− /*
2195− * Calculate the length of the extent being written to the selected
2196− * object. This is the minimum of the full length requested (len) or
2197− * the remainder of the current stripe being written to.
2198− */
2199− *oxlen = min_t(u64, len, su - su_offset);
2200−
2201− dout(" obj extent %llu~%llu\n", *oxoff, *oxlen);
2202− return 0;
2203−
2204−invalid:
2205− dout(" invalid layout\n");
2206− *ono = 0;
2207− *oxoff = 0;
2208− *oxlen = 0;
2209− return -EINVAL;
2210−}
2211−EXPORT_SYMBOL(ceph_calc_file_object_mapping);
2212−
22132142 /*
22142143 * Map an object into a PG.
22152144 *
net/ceph/striper.c+261−0
@@ -0,0 +1,261 @@
1+/* SPDX-License-Identifier: GPL-2.0 */
2+
3+#include <linux/ceph/ceph_debug.h>
4+
5+#include <linux/math64.h>
6+#include <linux/slab.h>
7+
8+#include <linux/ceph/striper.h>
9+#include <linux/ceph/types.h>
10+
11+/*
12+ * Map a file extent to a stripe unit within an object.
13+ * Fill in objno, offset into object, and object extent length (i.e. the
14+ * number of bytes mapped, less than or equal to @l->stripe_unit).
15+ *
16+ * Example for stripe_count = 3, stripes_per_object = 4:
17+ *
18+ * blockno | 0 3 6 9 | 1 4 7 10 | 2 5 8 11 | 12 15 18 21 | 13 16 19
19+ * stripeno | 0 1 2 3 | 0 1 2 3 | 0 1 2 3 | 4 5 6 7 | 4 5 6
20+ * stripepos | 0 | 1 | 2 | 0 | 1
21+ * objno | 0 | 1 | 2 | 3 | 4
22+ * objsetno | 0 | 1
23+ */
24+void ceph_calc_file_object_mapping(struct ceph_file_layout *l,
25+ u64 off, u64 len,
26+ u64 *objno, u64 *objoff, u32 *xlen)
27+{
28+ u32 stripes_per_object = l->object_size / l->stripe_unit;
29+ u64 blockno; /* which su in the file (i.e. globally) */
30+ u32 blockoff; /* offset into su */
31+ u64 stripeno; /* which stripe */
32+ u32 stripepos; /* which su in the stripe,
33+ which object in the object set */
34+ u64 objsetno; /* which object set */
35+ u32 objsetpos; /* which stripe in the object set */
36+
37+ blockno = div_u64_rem(off, l->stripe_unit, &blockoff);
38+ stripeno = div_u64_rem(blockno, l->stripe_count, &stripepos);
39+ objsetno = div_u64_rem(stripeno, stripes_per_object, &objsetpos);
40+
41+ *objno = objsetno * l->stripe_count + stripepos;
42+ *objoff = objsetpos * l->stripe_unit + blockoff;
43+ *xlen = min_t(u64, len, l->stripe_unit - blockoff);
44+}
45+EXPORT_SYMBOL(ceph_calc_file_object_mapping);
46+
47+/*
48+ * Return the last extent with given objno (@object_extents is sorted
49+ * by objno). If not found, return NULL and set @add_pos so that the
50+ * new extent can be added with list_add(add_pos, new_ex).
51+ */
52+static struct ceph_object_extent *
53+lookup_last(struct list_head *object_extents, u64 objno,
54+ struct list_head **add_pos)
55+{
56+ struct list_head *pos;
57+
58+ list_for_each_prev(pos, object_extents) {
59+ struct ceph_object_extent *ex =
60+ list_entry(pos, typeof(*ex), oe_item);
61+
62+ if (ex->oe_objno == objno)
63+ return ex;
64+
65+ if (ex->oe_objno < objno)
66+ break;
67+ }
68+
69+ *add_pos = pos;
70+ return NULL;
71+}
72+
73+static struct ceph_object_extent *
74+lookup_containing(struct list_head *object_extents, u64 objno,
75+ u64 objoff, u32 xlen)
76+{
77+ struct ceph_object_extent *ex;
78+
79+ list_for_each_entry(ex, object_extents, oe_item) {
80+ if (ex->oe_objno == objno &&
81+ ex->oe_off <= objoff &&
82+ ex->oe_off + ex->oe_len >= objoff + xlen) /* paranoia */
83+ return ex;
84+
85+ if (ex->oe_objno > objno)
86+ break;
87+ }
88+
89+ return NULL;
90+}
91+
92+/*
93+ * Map a file extent to a sorted list of object extents.
94+ *
95+ * We want only one (or as few as possible) object extents per object.
96+ * Adjacent object extents will be merged together, each returned object
97+ * extent may reverse map to multiple different file extents.
98+ *
99+ * Call @alloc_fn for each new object extent and @action_fn for each
100+ * mapped stripe unit, whether it was merged into an already allocated
101+ * object extent or started a new object extent.
102+ *
103+ * Newly allocated object extents are added to @object_extents.
104+ * To keep @object_extents sorted, successive calls to this function
105+ * must map successive file extents (i.e. the list of file extents that
106+ * are mapped using the same @object_extents must be sorted).
107+ *
108+ * The caller is responsible for @object_extents.
109+ */
110+int ceph_file_to_extents(struct ceph_file_layout *l, u64 off, u64 len,
111+ struct list_head *object_extents,
112+ struct ceph_object_extent *alloc_fn(void *arg),
113+ void *alloc_arg,
114+ ceph_object_extent_fn_t action_fn,
115+ void *action_arg)
116+{
117+ struct ceph_object_extent *last_ex, *ex;
118+
119+ while (len) {
120+ struct list_head *add_pos = NULL;
121+ u64 objno, objoff;
122+ u32 xlen;
123+
124+ ceph_calc_file_object_mapping(l, off, len, &objno, &objoff,
125+ &xlen);
126+
127+ last_ex = lookup_last(object_extents, objno, &add_pos);
128+ if (!last_ex || last_ex->oe_off + last_ex->oe_len != objoff) {
129+ ex = alloc_fn(alloc_arg);
130+ if (!ex)
131+ return -ENOMEM;
132+
133+ ex->oe_objno = objno;
134+ ex->oe_off = objoff;
135+ ex->oe_len = xlen;
136+ if (action_fn)
137+ action_fn(ex, xlen, action_arg);
138+
139+ if (!last_ex)
140+ list_add(&ex->oe_item, add_pos);
141+ else
142+ list_add(&ex->oe_item, &last_ex->oe_item);
143+ } else {
144+ last_ex->oe_len += xlen;
145+ if (action_fn)
146+ action_fn(last_ex, xlen, action_arg);
147+ }
148+
149+ off += xlen;
150+ len -= xlen;
151+ }
152+
153+ for (last_ex = list_first_entry(object_extents, typeof(*ex), oe_item),
154+ ex = list_next_entry(last_ex, oe_item);
155+ &ex->oe_item != object_extents;
156+ last_ex = ex, ex = list_next_entry(ex, oe_item)) {
157+ if (last_ex->oe_objno > ex->oe_objno ||
158+ (last_ex->oe_objno == ex->oe_objno &&
159+ last_ex->oe_off + last_ex->oe_len >= ex->oe_off)) {
160+ WARN(1, "%s: object_extents list not sorted!\n",
161+ __func__);
162+ return -EINVAL;
163+ }
164+ }
165+
166+ return 0;
167+}
168+EXPORT_SYMBOL(ceph_file_to_extents);
169+
170+/*
171+ * A stripped down, non-allocating version of ceph_file_to_extents(),
172+ * for when @object_extents is already populated.
173+ */
174+int ceph_iterate_extents(struct ceph_file_layout *l, u64 off, u64 len,
175+ struct list_head *object_extents,
176+ ceph_object_extent_fn_t action_fn,
177+ void *action_arg)
178+{
179+ while (len) {
180+ struct ceph_object_extent *ex;
181+ u64 objno, objoff;
182+ u32 xlen;
183+
184+ ceph_calc_file_object_mapping(l, off, len, &objno, &objoff,
185+ &xlen);
186+
187+ ex = lookup_containing(object_extents, objno, objoff, xlen);
188+ if (!ex) {
189+ WARN(1, "%s: objno %llu %llu~%u not found!\n",
190+ __func__, objno, objoff, xlen);
191+ return -EINVAL;
192+ }
193+
194+ action_fn(ex, xlen, action_arg);
195+
196+ off += xlen;
197+ len -= xlen;
198+ }
199+
200+ return 0;
201+}
202+EXPORT_SYMBOL(ceph_iterate_extents);
203+
204+/*
205+ * Reverse map an object extent to a sorted list of file extents.
206+ *
207+ * On success, the caller is responsible for:
208+ *
209+ * kfree(file_extents)
210+ */
211+int ceph_extent_to_file(struct ceph_file_layout *l,
212+ u64 objno, u64 objoff, u64 objlen,
213+ struct ceph_file_extent **file_extents,
214+ u32 *num_file_extents)
215+{
216+ u32 stripes_per_object = l->object_size / l->stripe_unit;
217+ u64 blockno; /* which su */
218+ u32 blockoff; /* offset into su */
219+ u64 stripeno; /* which stripe */
220+ u32 stripepos; /* which su in the stripe,
221+ which object in the object set */
222+ u64 objsetno; /* which object set */
223+ u32 i = 0;
224+
225+ if (!objlen) {
226+ *file_extents = NULL;
227+ *num_file_extents = 0;
228+ return 0;
229+ }
230+
231+ *num_file_extents = DIV_ROUND_UP_ULL(objoff + objlen, l->stripe_unit) -
232+ DIV_ROUND_DOWN_ULL(objoff, l->stripe_unit);
233+ *file_extents = kmalloc_array(*num_file_extents, sizeof(**file_extents),
234+ GFP_NOIO);
235+ if (!*file_extents)
236+ return -ENOMEM;
237+
238+ div_u64_rem(objoff, l->stripe_unit, &blockoff);
239+ while (objlen) {
240+ u64 off, len;
241+
242+ objsetno = div_u64_rem(objno, l->stripe_count, &stripepos);
243+ stripeno = div_u64(objoff, l->stripe_unit) +
244+ objsetno * stripes_per_object;
245+ blockno = stripeno * l->stripe_count + stripepos;
246+ off = blockno * l->stripe_unit + blockoff;
247+ len = min_t(u64, objlen, l->stripe_unit - blockoff);
248+
249+ (*file_extents)[i].fe_off = off;
250+ (*file_extents)[i].fe_len = len;
251+
252+ blockoff = 0;
253+ objoff += len;
254+ objlen -= len;
255+ i++;
256+ }
257+
258+ BUG_ON(i != *num_file_extents);
259+ return 0;
260+}
261+EXPORT_SYMBOL(ceph_extent_to_file);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t