Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 24 May 2010 14:37:52 +0000 (07:37 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 24 May 2010 14:37:52 +0000 (07:37 -0700)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client: (59 commits)
  ceph: reuse mon subscribe message instead of allocated anew
  ceph: avoid resending queued message to monitor
  ceph: Storage class should be before const qualifier
  ceph: all allocation functions should get gfp_mask
  ceph: specify max_bytes on readdir replies
  ceph: cleanup pool op strings
  ceph: Use kzalloc
  ceph: use common helper for aborted dir request invalidation
  ceph: cope with out of order (unsafe after safe) mds reply
  ceph: save peer feature bits in connection structure
  ceph: resync headers with userland
  ceph: use ceph. prefix for virtual xattrs
  ceph: throw out dirty caps metadata, data on session teardown
  ceph: attempt mds reconnect if mds closes our session
  ceph: clean up send_mds_reconnect interface
  ceph: wait for mds OPEN reply to indicate reconnect success
  ceph: only send cap releases when mds is OPEN|HUNG
  ceph: dicard cap releases on mds restart
  ceph: make mon client statfs handling more generic
  ceph: drop src address(es) from message header [new protocol feature]
  ...

1  2 
fs/ceph/file.c
fs/ceph/super.c

diff --combined fs/ceph/file.c
@@@ -317,16 -317,16 +317,16 @@@ void ceph_release_page_vector(struct pa
  /*
   * allocate a vector new pages
   */
- static struct page **alloc_page_vector(int num_pages)
+ struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags)
  {
        struct page **pages;
        int i;
  
-       pages = kmalloc(sizeof(*pages) * num_pages, GFP_NOFS);
+       pages = kmalloc(sizeof(*pages) * num_pages, flags);
        if (!pages)
                return ERR_PTR(-ENOMEM);
        for (i = 0; i < num_pages; i++) {
-               pages[i] = alloc_page(GFP_NOFS);
+               pages[i] = __page_cache_alloc(flags);
                if (pages[i] == NULL) {
                        ceph_release_page_vector(pages, i);
                        return ERR_PTR(-ENOMEM);
@@@ -540,7 -540,7 +540,7 @@@ static ssize_t ceph_sync_read(struct fi
                 * in sequence.
                 */
        } else {
-               pages = alloc_page_vector(num_pages);
+               pages = ceph_alloc_page_vector(num_pages, GFP_NOFS);
        }
        if (IS_ERR(pages))
                return PTR_ERR(pages);
@@@ -649,8 -649,8 +649,8 @@@ more
                                    do_sync,
                                    ci->i_truncate_seq, ci->i_truncate_size,
                                    &mtime, false, 2);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
+       if (!req)
+               return -ENOMEM;
  
        num_pages = calc_pages_for(pos, len);
  
                truncate_inode_pages_range(inode->i_mapping, pos, 
                                           (pos+len) | (PAGE_CACHE_SIZE-1));
        } else {
-               pages = alloc_page_vector(num_pages);
+               pages = ceph_alloc_page_vector(num_pages, GFP_NOFS);
                if (IS_ERR(pages)) {
                        ret = PTR_ERR(pages);
                        goto out;
@@@ -809,7 -809,7 +809,7 @@@ static ssize_t ceph_aio_write(struct ki
        struct file *file = iocb->ki_filp;
        struct inode *inode = file->f_dentry->d_inode;
        struct ceph_inode_info *ci = ceph_inode(inode);
-       struct ceph_osd_client *osdc = &ceph_client(inode->i_sb)->osdc;
+       struct ceph_osd_client *osdc = &ceph_sb_to_client(inode->i_sb)->osdc;
        loff_t endoff = pos + iov->iov_len;
        int got = 0;
        int ret, err;
@@@ -844,7 -844,8 +844,7 @@@ retry_snap
                if ((ret >= 0 || ret == -EIOCBQUEUED) &&
                    ((file->f_flags & O_SYNC) || IS_SYNC(file->f_mapping->host)
                     || ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_NEARFULL))) {
 -                      err = vfs_fsync_range(file, file->f_path.dentry,
 -                                            pos, pos + ret - 1, 1);
 +                      err = vfs_fsync_range(file, pos, pos + ret - 1, 1);
                        if (err < 0)
                                ret = err;
                }
diff --combined fs/ceph/super.c
@@@ -8,14 -8,11 +8,11 @@@
  #include <linux/module.h>
  #include <linux/mount.h>
  #include <linux/parser.h>
- #include <linux/rwsem.h>
  #include <linux/sched.h>
  #include <linux/seq_file.h>
  #include <linux/slab.h>
  #include <linux/statfs.h>
  #include <linux/string.h>
- #include <linux/version.h>
- #include <linux/vmalloc.h>
  
  #include "decode.h"
  #include "super.h"
@@@ -107,12 -104,40 +104,40 @@@ static int ceph_statfs(struct dentry *d
  static int ceph_syncfs(struct super_block *sb, int wait)
  {
        dout("sync_fs %d\n", wait);
-       ceph_osdc_sync(&ceph_client(sb)->osdc);
-       ceph_mdsc_sync(&ceph_client(sb)->mdsc);
+       ceph_osdc_sync(&ceph_sb_to_client(sb)->osdc);
+       ceph_mdsc_sync(&ceph_sb_to_client(sb)->mdsc);
        dout("sync_fs %d done\n", wait);
        return 0;
  }
  
+ static int default_congestion_kb(void)
+ {
+       int congestion_kb;
+       /*
+        * Copied from NFS
+        *
+        * congestion size, scale with available memory.
+        *
+        *  64MB:    8192k
+        * 128MB:   11585k
+        * 256MB:   16384k
+        * 512MB:   23170k
+        *   1GB:   32768k
+        *   2GB:   46340k
+        *   4GB:   65536k
+        *   8GB:   92681k
+        *  16GB:  131072k
+        *
+        * This allows larger machines to have larger/more transfers.
+        * Limit the default to 256M
+        */
+       congestion_kb = (16*int_sqrt(totalram_pages)) << (PAGE_SHIFT-10);
+       if (congestion_kb > 256*1024)
+               congestion_kb = 256*1024;
+       return congestion_kb;
+ }
  
  /**
   * ceph_show_options - Show mount options in /proc/mounts
@@@ -138,6 -163,35 +163,35 @@@ static int ceph_show_options(struct seq
                seq_puts(m, ",nocrc");
        if (args->flags & CEPH_OPT_NOASYNCREADDIR)
                seq_puts(m, ",noasyncreaddir");
+       if (args->mount_timeout != CEPH_MOUNT_TIMEOUT_DEFAULT)
+               seq_printf(m, ",mount_timeout=%d", args->mount_timeout);
+       if (args->osd_idle_ttl != CEPH_OSD_IDLE_TTL_DEFAULT)
+               seq_printf(m, ",osd_idle_ttl=%d", args->osd_idle_ttl);
+       if (args->osd_timeout != CEPH_OSD_TIMEOUT_DEFAULT)
+               seq_printf(m, ",osdtimeout=%d", args->osd_timeout);
+       if (args->osd_keepalive_timeout != CEPH_OSD_KEEPALIVE_DEFAULT)
+               seq_printf(m, ",osdkeepalivetimeout=%d",
+                        args->osd_keepalive_timeout);
+       if (args->wsize)
+               seq_printf(m, ",wsize=%d", args->wsize);
+       if (args->rsize != CEPH_MOUNT_RSIZE_DEFAULT)
+               seq_printf(m, ",rsize=%d", args->rsize);
+       if (args->congestion_kb != default_congestion_kb())
+               seq_printf(m, ",write_congestion_kb=%d", args->congestion_kb);
+       if (args->caps_wanted_delay_min != CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT)
+               seq_printf(m, ",caps_wanted_delay_min=%d",
+                        args->caps_wanted_delay_min);
+       if (args->caps_wanted_delay_max != CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT)
+               seq_printf(m, ",caps_wanted_delay_max=%d",
+                          args->caps_wanted_delay_max);
+       if (args->cap_release_safety != CEPH_CAP_RELEASE_SAFETY_DEFAULT)
+               seq_printf(m, ",cap_release_safety=%d",
+                          args->cap_release_safety);
+       if (args->max_readdir != CEPH_MAX_READDIR_DEFAULT)
+               seq_printf(m, ",readdir_max_entries=%d", args->max_readdir);
+       if (args->max_readdir_bytes != CEPH_MAX_READDIR_BYTES_DEFAULT)
+               seq_printf(m, ",readdir_max_bytes=%d", args->max_readdir_bytes);
        if (strcmp(args->snapdir_name, CEPH_SNAPDIRNAME_DEFAULT))
                seq_printf(m, ",snapdirname=%s", args->snapdir_name);
        if (args->name)
@@@ -161,35 -215,6 +215,6 @@@ static void ceph_inode_init_once(void *
        inode_init_once(&ci->vfs_inode);
  }
  
- static int default_congestion_kb(void)
- {
-       int congestion_kb;
-       /*
-        * Copied from NFS
-        *
-        * congestion size, scale with available memory.
-        *
-        *  64MB:    8192k
-        * 128MB:   11585k
-        * 256MB:   16384k
-        * 512MB:   23170k
-        *   1GB:   32768k
-        *   2GB:   46340k
-        *   4GB:   65536k
-        *   8GB:   92681k
-        *  16GB:  131072k
-        *
-        * This allows larger machines to have larger/more transfers.
-        * Limit the default to 256M
-        */
-       congestion_kb = (16*int_sqrt(totalram_pages)) << (PAGE_SHIFT-10);
-       if (congestion_kb > 256*1024)
-               congestion_kb = 256*1024;
-       return congestion_kb;
- }
  static int __init init_caches(void)
  {
        ceph_inode_cachep = kmem_cache_create("ceph_inode_info",
@@@ -308,7 -333,9 +333,9 @@@ enum 
        Opt_osd_idle_ttl,
        Opt_caps_wanted_delay_min,
        Opt_caps_wanted_delay_max,
+       Opt_cap_release_safety,
        Opt_readdir_max_entries,
+       Opt_readdir_max_bytes,
        Opt_congestion_kb,
        Opt_last_int,
        /* int args above */
@@@ -339,7 -366,9 +366,9 @@@ static match_table_t arg_tokens = 
        {Opt_osd_idle_ttl, "osd_idle_ttl=%d"},
        {Opt_caps_wanted_delay_min, "caps_wanted_delay_min=%d"},
        {Opt_caps_wanted_delay_max, "caps_wanted_delay_max=%d"},
+       {Opt_cap_release_safety, "cap_release_safety=%d"},
        {Opt_readdir_max_entries, "readdir_max_entries=%d"},
+       {Opt_readdir_max_bytes, "readdir_max_bytes=%d"},
        {Opt_congestion_kb, "write_congestion_kb=%d"},
        /* int args above */
        {Opt_snapdirname, "snapdirname=%s"},
@@@ -388,8 -417,9 +417,9 @@@ static struct ceph_mount_args *parse_mo
        args->caps_wanted_delay_max = CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT;
        args->rsize = CEPH_MOUNT_RSIZE_DEFAULT;
        args->snapdir_name = kstrdup(CEPH_SNAPDIRNAME_DEFAULT, GFP_KERNEL);
-       args->cap_release_safety = CEPH_CAPS_PER_RELEASE * 4;
-       args->max_readdir = 1024;
+       args->cap_release_safety = CEPH_CAP_RELEASE_SAFETY_DEFAULT;
+       args->max_readdir = CEPH_MAX_READDIR_DEFAULT;
+       args->max_readdir_bytes = CEPH_MAX_READDIR_BYTES_DEFAULT;
        args->congestion_kb = default_congestion_kb();
  
        /* ip1[:port1][,ip2[:port2]...]:/subdir/in/fs */
                case Opt_readdir_max_entries:
                        args->max_readdir = intval;
                        break;
+               case Opt_readdir_max_bytes:
+                       args->max_readdir_bytes = intval;
+                       break;
                case Opt_congestion_kb:
                        args->congestion_kb = intval;
                        break;
@@@ -682,9 -715,10 +715,10 @@@ int ceph_check_fsid(struct ceph_client 
  /*
   * true if we have the mon map (and have thus joined the cluster)
   */
- static int have_mon_map(struct ceph_client *client)
+ static int have_mon_and_osd_map(struct ceph_client *client)
  {
-       return client->monc.monmap && client->monc.monmap->epoch;
+       return client->monc.monmap && client->monc.monmap->epoch &&
+              client->osdc.osdmap && client->osdc.osdmap->epoch;
  }
  
  /*
@@@ -762,7 -796,7 +796,7 @@@ static int ceph_mount(struct ceph_clien
        if (err < 0)
                goto out;
  
-       while (!have_mon_map(client)) {
+       while (!have_mon_and_osd_map(client)) {
                err = -EIO;
                if (timeout && time_after_eq(jiffies, started + timeout))
                        goto out;
                /* wait */
                dout("mount waiting for mon_map\n");
                err = wait_event_interruptible_timeout(client->auth_wq,
-                              have_mon_map(client) || (client->auth_err < 0),
-                              timeout);
+                      have_mon_and_osd_map(client) || (client->auth_err < 0),
+                      timeout);
                if (err == -EINTR || err == -ERESTARTSYS)
                        goto out;
                if (client->auth_err < 0) {
@@@ -884,6 -918,8 +918,8 @@@ static int ceph_compare_super(struct su
  /*
   * construct our own bdi so we can control readahead, etc.
   */
+ static atomic_long_t bdi_seq = ATOMIC_INIT(0);
  static int ceph_register_bdi(struct super_block *sb, struct ceph_client *client)
  {
        int err;
                client->backing_dev_info.ra_pages =
                        (client->mount_args->rsize + PAGE_CACHE_SIZE - 1)
                        >> PAGE_SHIFT;
-       err = bdi_register_dev(&client->backing_dev_info, sb->s_dev);
+       err = bdi_register(&client->backing_dev_info, NULL, "ceph-%d",
+                          atomic_long_inc_return(&bdi_seq));
        if (!err)
                sb->s_bdi = &client->backing_dev_info;
        return err;
@@@ -932,9 -969,9 +969,9 @@@ static int ceph_get_sb(struct file_syst
                goto out;
        }
  
-       if (ceph_client(sb) != client) {
+       if (ceph_sb_to_client(sb) != client) {
                ceph_destroy_client(client);
-               client = ceph_client(sb);
+               client = ceph_sb_to_client(sb);
                dout("get_sb got existing client %p\n", client);
        } else {
                dout("get_sb using new client %p\n", client);
  
  out_splat:
        ceph_mdsc_close_sessions(&client->mdsc);
 -      up_write(&sb->s_umount);
 -      deactivate_super(sb);
 +      deactivate_locked_super(sb);
        goto out_final;
  
  out: