diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-10 15:25:30 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-10 15:25:30 -0400 |
| commit | b284d4d5a6785f8cd07eda2646a95782373cd01e (patch) | |
| tree | 62d835dcb6a6eb30fe9b0ebad7aeba4b4234b1d6 | |
| parent | a7726f6b61e8917e73101bb8071facdff7ec5d72 (diff) | |
| parent | 9122eed5281e89bdb02162a8ecb3cc13ffc8985e (diff) | |
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
...
35 files changed, 2558 insertions, 1920 deletions
diff --git a/Documentation/filesystems/ceph.txt b/Documentation/filesystems/ceph.txt index 0b302a11718a..d7f011ddc150 100644 --- a/Documentation/filesystems/ceph.txt +++ b/Documentation/filesystems/ceph.txt | |||
| @@ -62,6 +62,18 @@ subdirectories, and a summation of all nested file sizes. This makes | |||
| 62 | the identification of large disk space consumers relatively quick, as | 62 | the identification of large disk space consumers relatively quick, as |
| 63 | no 'du' or similar recursive scan of the file system is required. | 63 | no 'du' or similar recursive scan of the file system is required. |
| 64 | 64 | ||
| 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. | ||
| 65 | 77 | ||
| 66 | Mount Syntax | 78 | Mount Syntax |
| 67 | ============ | 79 | ============ |
| @@ -137,6 +149,10 @@ Mount Options | |||
| 137 | noasyncreaddir | 149 | noasyncreaddir |
| 138 | Do not use the dcache as above for readdir. | 150 | Do not use the dcache as above for readdir. |
| 139 | 151 | ||
| 152 | noquotadf | ||
| 153 | Report overall filesystem usage in statfs instead of using the root | ||
| 154 | directory quota. | ||
| 155 | |||
| 140 | More Information | 156 | More Information |
| 141 | ================ | 157 | ================ |
| 142 | 158 | ||
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 1e03b04819c8..07dc5419bd63 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include <linux/ceph/osd_client.h> | 32 | #include <linux/ceph/osd_client.h> |
| 33 | #include <linux/ceph/mon_client.h> | 33 | #include <linux/ceph/mon_client.h> |
| 34 | #include <linux/ceph/cls_lock_client.h> | 34 | #include <linux/ceph/cls_lock_client.h> |
| 35 | #include <linux/ceph/striper.h> | ||
| 35 | #include <linux/ceph/decode.h> | 36 | #include <linux/ceph/decode.h> |
| 36 | #include <linux/parser.h> | 37 | #include <linux/parser.h> |
| 37 | #include <linux/bsearch.h> | 38 | #include <linux/bsearch.h> |
| @@ -200,95 +201,81 @@ struct rbd_client { | |||
| 200 | }; | 201 | }; |
| 201 | 202 | ||
| 202 | struct rbd_img_request; | 203 | 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 *); | ||
| 209 | 204 | ||
| 210 | enum obj_request_type { | 205 | 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 */ | ||
| 212 | }; | 210 | }; |
| 213 | 211 | ||
| 214 | enum obj_operation_type { | 212 | enum obj_operation_type { |
| 213 | OBJ_OP_READ = 1, | ||
| 215 | OBJ_OP_WRITE, | 214 | OBJ_OP_WRITE, |
| 216 | OBJ_OP_READ, | ||
| 217 | OBJ_OP_DISCARD, | 215 | OBJ_OP_DISCARD, |
| 218 | }; | 216 | }; |
| 219 | 217 | ||
| 220 | enum obj_req_flags { | 218 | /* |
| 221 | OBJ_REQ_DONE, /* completion flag: not done = 0, done = 1 */ | 219 | * Writes go through the following state machine to deal with |
| 222 | OBJ_REQ_IMG_DATA, /* object usage: standalone = 0, image = 1 */ | 220 | * layering: |
| 223 | OBJ_REQ_KNOWN, /* EXISTS flag valid: no = 0, yes = 1 */ | 221 | * |
| 224 | OBJ_REQ_EXISTS, /* target exists: no = 0, yes = 1 */ | 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, | ||
| 225 | }; | 238 | }; |
| 226 | 239 | ||
| 227 | struct rbd_obj_request { | 240 | struct rbd_obj_request { |
| 228 | u64 object_no; | 241 | struct ceph_object_extent ex; |
| 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 | */ | ||
| 249 | union { | 242 | union { |
| 250 | struct rbd_obj_request *obj_request; /* STAT op */ | 243 | bool tried_parent; /* for reads */ |
| 251 | struct { | 244 | enum rbd_obj_write_state write_state; /* for writes */ |
| 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 | }; | ||
| 257 | }; | 245 | }; |
| 258 | u32 which; /* posn image request list */ | ||
| 259 | 246 | ||
| 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 | |||
| 261 | union { | 251 | union { |
| 262 | struct bio *bio_list; | 252 | |
