aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-07 17:38:18 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-07 17:38:18 -0400
commit7035cdf36d5c4d913f68ff97e1c2e5603500d946 (patch)
treeeee5680c16771cb23bc6d3a47bc7b6f350171b22 /fs/ceph
parent6432f2128414edbea5fd4f6c4fa4c28d0e1c6151 (diff)
parent6285bc231277419255f3498d3eb5ddc9f8e7fe79 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client
Pull ceph updates from Sage Weil: "The bulk of this pull is a series from Alex that refactors and cleans up the RBD code to lay the groundwork for supporting the new image format and evolving feature set. There are also some cleanups in libceph, and for ceph there's fixed validation of file striping layouts and a bugfix in the code handling a shrinking MDS cluster." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client: (71 commits) ceph: avoid 32-bit page index overflow ceph: return EIO on invalid layout on GET_DATALOC ioctl rbd: BUG on invalid layout ceph: propagate layout error on osd request creation libceph: check for invalid mapping ceph: convert to use le32_add_cpu() ceph: Fix oops when handling mdsmap that decreases max_mds rbd: update remaining header fields for v2 rbd: get snapshot name for a v2 image rbd: get the snapshot context for a v2 image rbd: get image features for a v2 image rbd: get the object prefix for a v2 rbd image rbd: add code to get the size of a v2 rbd image rbd: lay out header probe infrastructure rbd: encapsulate code that gets snapshot info rbd: add an rbd features field rbd: don't use index in __rbd_add_snap_dev() rbd: kill create_snap sysfs entry rbd: define rbd_dev_image_id() rbd: define some new format constants ...
Diffstat (limited to 'fs/ceph')
-rw-r--r--fs/ceph/addr.c19
-rw-r--r--fs/ceph/caps.c2
-rw-r--r--fs/ceph/file.c4
-rw-r--r--fs/ceph/ioctl.c8
-rw-r--r--fs/ceph/mds_client.c3
-rw-r--r--fs/ceph/super.c37
6 files changed, 46 insertions, 27 deletions
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index 452e71a1b753..22b6e4583faa 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -205,7 +205,7 @@ static int readpage_nounlock(struct file *filp, struct page *page)
205 dout("readpage inode %p file %p page %p index %lu\n", 205 dout("readpage inode %p file %p page %p index %lu\n",
206 inode, filp, page, page->index); 206 inode, filp, page, page->index);
207 err = ceph_osdc_readpages(osdc, ceph_vino(inode), &ci->i_layout, 207 err = ceph_osdc_readpages(osdc, ceph_vino(inode), &ci->i_layout,
208 page->index << PAGE_CACHE_SHIFT, &len, 208 (u64) page_offset(page), &len,
209 ci->i_truncate_seq, ci->i_truncate_size, 209 ci->i_truncate_seq, ci->i_truncate_size,
210 &page, 1, 0); 210 &page, 1, 0);
211 if (err == -ENOENT) 211 if (err == -ENOENT)
@@ -286,7 +286,7 @@ static int start_read(struct inode *inode, struct list_head *page_list, int max)
286 int nr_pages = 0; 286 int nr_pages = 0;
287 int ret; 287 int ret;
288 288
289 off = page->index << PAGE_CACHE_SHIFT; 289 off = (u64) page_offset(page);
290 290
291 /* count pages */ 291 /* count pages */
292 next_index = page->index; 292 next_index = page->index;
@@ -308,8 +308,8 @@ static int start_read(struct inode *inode, struct list_head *page_list, int max)
308 NULL, 0, 308 NULL, 0,
309 ci->i_truncate_seq, ci->i_truncate_size, 309 ci->i_truncate_seq, ci->i_truncate_size,
310 NULL, false, 1, 0); 310 NULL, false, 1, 0);
311 if (!req) 311 if (IS_ERR(req))
312 return -ENOMEM; 312 return PTR_ERR(req);
313 313
314 /* build page vector */ 314 /* build page vector */
315 nr_pages = len >> PAGE_CACHE_SHIFT; 315 nr_pages = len >> PAGE_CACHE_SHIFT;
@@ -426,7 +426,7 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
426 struct ceph_inode_info *ci; 426 struct ceph_inode_info *ci;
427 struct ceph_fs_client *fsc; 427 struct ceph_fs_client *fsc;
428 struct ceph_osd_client *osdc; 428 struct ceph_osd_client *osdc;
429 loff_t page_off = page->index << PAGE_CACHE_SHIFT; 429 loff_t page_off = page_offset(page);
430 int len = PAGE_CACHE_SIZE; 430 int len = PAGE_CACHE_SIZE;
431 loff_t i_size; 431 loff_t i_size;
432 int err = 0; 432 int err = 0;
@@ -817,8 +817,7 @@ get_more_pages:
817 /* ok */ 817 /* ok */
818 if (locked_pages == 0) { 818 if (locked_pages == 0) {
819 /* prepare async write request */ 819 /* prepare async write request */
820 offset = (unsigned long long)page->index 820 offset = (u64) page_offset(page);
821 << PAGE_CACHE_SHIFT;
822 len = wsize; 821 len = wsize;
823 req = ceph_osdc_new_request(&fsc->client->osdc, 822 req = ceph_osdc_new_request(&fsc->client->osdc,
824 &ci->i_layout, 823 &ci->i_layout,
@@ -832,8 +831,8 @@ get_more_pages:
832 ci->i_truncate_size, 831 ci->i_truncate_size,
833 &inode->i_mtime, true, 1, 0); 832 &inode->i_mtime, true, 1, 0);
834 833
835 if (!req) { 834 if (IS_ERR(req)) {
836 rc = -ENOMEM; 835 rc = PTR_ERR(req);
837 unlock_page(page); 836 unlock_page(page);
838 break; 837 break;
839 } 838 }
@@ -1180,7 +1179,7 @@ static int ceph_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
1180 struct inode *inode = vma->vm_file->f_dentry->d_inode; 1179 struct inode *inode = vma->vm_file->f_dentry->d_inode;
1181 struct page *page = vmf->page; 1180 struct page *page = vmf->page;
1182 struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc; 1181 struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc;
1183 loff_t off = page->index << PAGE_CACHE_SHIFT; 1182 loff_t off = page_offset(page);
1184 loff_t size, len; 1183 loff_t size, len;
1185 int ret; 1184 int ret;
1186 1185
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 620daad201db..3251e9cc6401 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -1005,7 +1005,7 @@ static void __queue_cap_release(struct ceph_mds_session *session,
1005 1005
1006 BUG_ON(msg->front.iov_len + sizeof(*item) > PAGE_CACHE_SIZE); 1006 BUG_ON(msg->front.iov_len + sizeof(*item) > PAGE_CACHE_SIZE);
1007 head = msg->front.iov_base; 1007 head = msg->front.iov_base;
1008 head->num = cpu_to_le32(le32_to_cpu(head->num) + 1); 1008 le32_add_cpu(&head->num, 1);
1009 item = msg->front.iov_base + msg->front.iov_len; 1009 item = msg->front.iov_base + msg->front.iov_len;
1010 item->ino = cpu_to_le64(ino); 1010 item->ino = cpu_to_le64(ino);
1011 item->cap_id = cpu_to_le64(cap_id); 1011 item->cap_id = cpu_to_le64(cap_id);
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index ecebbc09bfc7..5840d2aaed15 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -536,8 +536,8 @@ more:
536 do_sync, 536 do_sync,
537 ci->i_truncate_seq, ci->i_truncate_size, 537 ci->i_truncate_seq, ci->i_truncate_size,
538 &mtime, false, 2, page_align); 538 &mtime, false, 2, page_align);
539 if (!req) 539 if (IS_ERR(req))
540 return -ENOMEM; 540 return PTR_ERR(req);
541 541
542 if (file->f_flags & O_DIRECT) { 542 if (file->f_flags & O_DIRECT) {
543 pages = ceph_get_direct_page_vector(data, num_pages, false); 543 pages = ceph_get_direct_page_vector(data, num_pages, false);
diff --git a/fs/ceph/ioctl.c b/fs/ceph/ioctl.c
index 1396ceb46797..36549a46e311 100644
--- a/fs/ceph/ioctl.c
+++ b/fs/ceph/ioctl.c
@@ -187,14 +187,18 @@ static long ceph_ioctl_get_dataloc(struct file *file, void __user *arg)
187 u64 tmp; 187 u64 tmp;
188 struct ceph_object_layout ol; 188 struct ceph_object_layout ol;
189 struct ceph_pg pgid; 189 struct ceph_pg pgid;
190 int r;
190 191
191 /* copy and validate */ 192 /* copy and validate */
192 if (copy_from_user(&dl, arg, sizeof(dl))) 193 if (copy_from_user(&dl, arg, sizeof(dl)))
193 return -EFAULT; 194 return -EFAULT;
194 195
195 down_read(&osdc->map_sem); 196 down_read(&osdc->map_sem);
196 ceph_calc_file_object_mapping(&ci->i_layout, dl.file_offset, &len, 197 r = ceph_calc_file_object_mapping(&ci->i_layout, dl.file_offset, &len,
197 &dl.object_no, &dl.object_offset, &olen); 198 &dl.object_no, &dl.object_offset,
199 &olen);
200 if (r < 0)
201 return -EIO;
198 dl.file_offset -= dl.object_offset; 202 dl.file_offset -= dl.object_offset;
199 dl.object_size = ceph_file_layout_object_size(ci->i_layout); 203 dl.object_size = ceph_file_layout_object_size(ci->i_layout);
200 dl.block_size = ceph_file_layout_su(ci->i_layout); 204 dl.block_size = ceph_file_layout_su(ci->i_layout);
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index a5a735422aa7..1bcf712655d9 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -2625,7 +2625,8 @@ static void check_new_map(struct ceph_mds_client *mdsc,
2625 ceph_mdsmap_is_laggy(newmap, i) ? " (laggy)" : "", 2625 ceph_mdsmap_is_laggy(newmap, i) ? " (laggy)" : "",
2626 session_state_name(s->s_state)); 2626 session_state_name(s->s_state));
2627 2627
2628 if (memcmp(ceph_mdsmap_get_addr(oldmap, i), 2628 if (i >= newmap->m_max_mds ||
2629 memcmp(ceph_mdsmap_get_addr(oldmap, i),
2629 ceph_mdsmap_get_addr(newmap, i), 2630 ceph_mdsmap_get_addr(newmap, i),
2630 sizeof(struct ceph_entity_addr))) { 2631 sizeof(struct ceph_entity_addr))) {
2631 if (s->s_state == CEPH_MDS_SESSION_OPENING) { 2632 if (s->s_state == CEPH_MDS_SESSION_OPENING) {
diff --git a/fs/ceph/super.c b/fs/ceph/super.c
index 3a42d9326378..2eb43f211325 100644
--- a/fs/ceph/super.c
+++ b/fs/ceph/super.c
@@ -307,7 +307,10 @@ static int parse_mount_options(struct ceph_mount_options **pfsopt,
307{ 307{
308 struct ceph_mount_options *fsopt; 308 struct ceph_mount_options *fsopt;
309 const char *dev_name_end; 309 const char *dev_name_end;
310 int err = -ENOMEM; 310 int err;
311
312 if (!dev_name || !*dev_name)
313 return -EINVAL;
311 314
312 fsopt = kzalloc(sizeof(*fsopt), GFP_KERNEL); 315 fsopt = kzalloc(sizeof(*fsopt), GFP_KERNEL);
313 if (!fsopt) 316 if (!fsopt)
@@ -328,21 +331,33 @@ static int parse_mount_options(struct ceph_mount_options **pfsopt,
328 fsopt->max_readdir_bytes = CEPH_MAX_READDIR_BYTES_DEFAULT; 331 fsopt->max_readdir_bytes = CEPH_MAX_READDIR_BYTES_DEFAULT;
329 fsopt->congestion_kb = default_congestion_kb(); 332 fsopt->congestion_kb = default_congestion_kb();
330 333
331 /* ip1[:port1][,ip2[:port2]...]:/subdir/in/fs */ 334 /*
335 * Distinguish the server list from the path in "dev_name".
336 * Internally we do not include the leading '/' in the path.
337 *
338 * "dev_name" will look like:
339 * <server_spec>[,<server_spec>...]:[<path>]
340 * where
341 * <server_spec> is <ip>[:<port>]
342 * <path> is optional, but if present must begin with '/'
343 */
344 dev_name_end = strchr(dev_name, '/');
345 if (dev_name_end) {
346 /* skip over leading '/' for path */
347 *path = dev_name_end + 1;
348 } else {
349 /* path is empty */
350 dev_name_end = dev_name + strlen(dev_name);
351 *path = dev_name_end;
352 }
332 err = -EINVAL; 353 err = -EINVAL;
333 if (!dev_name) 354 dev_name_end--; /* back up to ':' separator */
334 goto out; 355 if (*dev_name_end != ':') {
335 *path = strstr(dev_name, ":/"); 356 pr_err("device name is missing path (no : separator in %s)\n",
336 if (*path == NULL) {
337 pr_err("device name is missing path (no :/ in %s)\n",
338 dev_name); 357 dev_name);
339 goto out; 358 goto out;
340 } 359 }
341 dev_name_end = *path;
342 dout("device name '%.*s'\n", (int)(dev_name_end - dev_name), dev_name); 360 dout("device name '%.*s'\n", (int)(dev_name_end - dev_name), dev_name);
343
344 /* path on server */
345 *path += 2;
346 dout("server path '%s'\n", *path); 361 dout("server path '%s'\n", *path);
347 362
348 *popt = ceph_parse_options(options, dev_name, dev_name_end, 363 *popt = ceph_parse_options(options, dev_name, dev_name_end,