Commit 0adfc56c authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client

* git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client:
  rbd: use watch/notify for changes in rbd header
  libceph: add lingering request and watch/notify event framework
  rbd: update email address in Documentation
  ceph: rename dentry_release -> d_release, fix comment
  ceph: add request to the tail of unsafe write list
  ceph: remove request from unsafe list if it is canceled/timed out
  ceph: move readahead default to fs/ceph from libceph
  ceph: add ino32 mount option
  ceph: update common header files
  ceph: remove debugfs debug cruft
  libceph: fix osd request queuing on osdmap updates
  ceph: preserve I_COMPLETE across rename
  libceph: Fix base64-decoding when input ends in newline.
parents f23eb2b2 59c2be1e
What: /sys/bus/rbd/ What: /sys/bus/rbd/
Date: November 2010 Date: November 2010
Contact: Yehuda Sadeh <yehuda@hq.newdream.net>, Contact: Yehuda Sadeh <yehuda@newdream.net>,
Sage Weil <sage@newdream.net> Sage Weil <sage@newdream.net>
Description: Description:
......
This diff is collapsed.
...@@ -210,8 +210,6 @@ int ceph_fs_debugfs_init(struct ceph_fs_client *fsc) ...@@ -210,8 +210,6 @@ int ceph_fs_debugfs_init(struct ceph_fs_client *fsc)
if (!fsc->debugfs_congestion_kb) if (!fsc->debugfs_congestion_kb)
goto out; goto out;
dout("a\n");
snprintf(name, sizeof(name), "../../bdi/%s", snprintf(name, sizeof(name), "../../bdi/%s",
dev_name(fsc->backing_dev_info.dev)); dev_name(fsc->backing_dev_info.dev));
fsc->debugfs_bdi = fsc->debugfs_bdi =
...@@ -221,7 +219,6 @@ int ceph_fs_debugfs_init(struct ceph_fs_client *fsc) ...@@ -221,7 +219,6 @@ int ceph_fs_debugfs_init(struct ceph_fs_client *fsc)
if (!fsc->debugfs_bdi) if (!fsc->debugfs_bdi)
goto out; goto out;
dout("b\n");
fsc->debugfs_mdsmap = debugfs_create_file("mdsmap", fsc->debugfs_mdsmap = debugfs_create_file("mdsmap",
0600, 0600,
fsc->client->debugfs_dir, fsc->client->debugfs_dir,
...@@ -230,7 +227,6 @@ int ceph_fs_debugfs_init(struct ceph_fs_client *fsc) ...@@ -230,7 +227,6 @@ int ceph_fs_debugfs_init(struct ceph_fs_client *fsc)
if (!fsc->debugfs_mdsmap) if (!fsc->debugfs_mdsmap)
goto out; goto out;
dout("ca\n");
fsc->debugfs_mdsc = debugfs_create_file("mdsc", fsc->debugfs_mdsc = debugfs_create_file("mdsc",
0600, 0600,
fsc->client->debugfs_dir, fsc->client->debugfs_dir,
...@@ -239,7 +235,6 @@ int ceph_fs_debugfs_init(struct ceph_fs_client *fsc) ...@@ -239,7 +235,6 @@ int ceph_fs_debugfs_init(struct ceph_fs_client *fsc)
if (!fsc->debugfs_mdsc) if (!fsc->debugfs_mdsc)
goto out; goto out;
dout("da\n");
fsc->debugfs_caps = debugfs_create_file("caps", fsc->debugfs_caps = debugfs_create_file("caps",
0400, 0400,
fsc->client->debugfs_dir, fsc->client->debugfs_dir,
...@@ -248,7 +243,6 @@ int ceph_fs_debugfs_init(struct ceph_fs_client *fsc) ...@@ -248,7 +243,6 @@ int ceph_fs_debugfs_init(struct ceph_fs_client *fsc)
if (!fsc->debugfs_caps) if (!fsc->debugfs_caps)
goto out; goto out;
dout("ea\n");
fsc->debugfs_dentry_lru = debugfs_create_file("dentry_lru", fsc->debugfs_dentry_lru = debugfs_create_file("dentry_lru",
0600, 0600,
fsc->client->debugfs_dir, fsc->client->debugfs_dir,
......
...@@ -161,7 +161,7 @@ static int __dcache_readdir(struct file *filp, ...@@ -161,7 +161,7 @@ static int __dcache_readdir(struct file *filp,
filp->f_pos = di->offset; filp->f_pos = di->offset;
err = filldir(dirent, dentry->d_name.name, err = filldir(dirent, dentry->d_name.name,
dentry->d_name.len, di->offset, dentry->d_name.len, di->offset,
dentry->d_inode->i_ino, ceph_translate_ino(dentry->d_sb, dentry->d_inode->i_ino),
dentry->d_inode->i_mode >> 12); dentry->d_inode->i_mode >> 12);
if (last) { if (last) {
...@@ -245,15 +245,17 @@ static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -245,15 +245,17 @@ static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir)
dout("readdir off 0 -> '.'\n"); dout("readdir off 0 -> '.'\n");
if (filldir(dirent, ".", 1, ceph_make_fpos(0, 0), if (filldir(dirent, ".", 1, ceph_make_fpos(0, 0),
inode->i_ino, inode->i_mode >> 12) < 0) ceph_translate_ino(inode->i_sb, inode->i_ino),
inode->i_mode >> 12) < 0)
return 0; return 0;
filp->f_pos = 1; filp->f_pos = 1;
off = 1; off = 1;
} }
if (filp->f_pos == 1) { if (filp->f_pos == 1) {
ino_t ino = filp->f_dentry->d_parent->d_inode->i_ino;
dout("readdir off 1 -> '..'\n"); dout("readdir off 1 -> '..'\n");
if (filldir(dirent, "..", 2, ceph_make_fpos(0, 1), if (filldir(dirent, "..", 2, ceph_make_fpos(0, 1),
filp->f_dentry->d_parent->d_inode->i_ino, ceph_translate_ino(inode->i_sb, ino),
inode->i_mode >> 12) < 0) inode->i_mode >> 12) < 0)
return 0; return 0;
filp->f_pos = 2; filp->f_pos = 2;
...@@ -377,7 +379,8 @@ static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -377,7 +379,8 @@ static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir)
if (filldir(dirent, if (filldir(dirent,
rinfo->dir_dname[off - fi->offset], rinfo->dir_dname[off - fi->offset],
rinfo->dir_dname_len[off - fi->offset], rinfo->dir_dname_len[off - fi->offset],
pos, ino, ftype) < 0) { pos,
ceph_translate_ino(inode->i_sb, ino), ftype) < 0) {
dout("filldir stopping us...\n"); dout("filldir stopping us...\n");
return 0; return 0;
} }
...@@ -1024,14 +1027,13 @@ static int ceph_d_revalidate(struct dentry *dentry, struct nameidata *nd) ...@@ -1024,14 +1027,13 @@ static int ceph_d_revalidate(struct dentry *dentry, struct nameidata *nd)
} }
/* /*
* When a dentry is released, clear the dir I_COMPLETE if it was part * Release our ceph_dentry_info.
* of the current dir gen or if this is in the snapshot namespace.
*/ */
static void ceph_dentry_release(struct dentry *dentry) static void ceph_d_release(struct dentry *dentry)
{ {
struct ceph_dentry_info *di = ceph_dentry(dentry); struct ceph_dentry_info *di = ceph_dentry(dentry);
dout("dentry_release %p\n", dentry); dout("d_release %p\n", dentry);
if (di) { if (di) {
ceph_dentry_lru_del(dentry); ceph_dentry_lru_del(dentry);
if (di->lease_session) if (di->lease_session)
...@@ -1256,14 +1258,14 @@ const struct inode_operations ceph_dir_iops = { ...@@ -1256,14 +1258,14 @@ const struct inode_operations ceph_dir_iops = {
const struct dentry_operations ceph_dentry_ops = { const struct dentry_operations ceph_dentry_ops = {
.d_revalidate = ceph_d_revalidate, .d_revalidate = ceph_d_revalidate,
.d_release = ceph_dentry_release, .d_release = ceph_d_release,
}; };
const struct dentry_operations ceph_snapdir_dentry_ops = { const struct dentry_operations ceph_snapdir_dentry_ops = {
.d_revalidate = ceph_snapdir_d_revalidate, .d_revalidate = ceph_snapdir_d_revalidate,
.d_release = ceph_dentry_release, .d_release = ceph_d_release,
}; };
const struct dentry_operations ceph_snap_dentry_ops = { const struct dentry_operations ceph_snap_dentry_ops = {
.d_release = ceph_dentry_release, .d_release = ceph_d_release,
}; };
...@@ -564,11 +564,19 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data, ...@@ -564,11 +564,19 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data,
* start_request so that a tid has been assigned. * start_request so that a tid has been assigned.
*/ */
spin_lock(&ci->i_unsafe_lock); spin_lock(&ci->i_unsafe_lock);
list_add(&req->r_unsafe_item, &ci->i_unsafe_writes); list_add_tail(&req->r_unsafe_item,
&ci->i_unsafe_writes);
spin_unlock(&ci->i_unsafe_lock); spin_unlock(&ci->i_unsafe_lock);
ceph_get_cap_refs(ci, CEPH_CAP_FILE_WR); ceph_get_cap_refs(ci, CEPH_CAP_FILE_WR);
} }
ret = ceph_osdc_wait_request(&fsc->client->osdc, req); ret = ceph_osdc_wait_request(&fsc->client->osdc, req);
if (ret < 0 && req->r_safe_callback) {
spin_lock(&ci->i_unsafe_lock);
list_del_init(&req->r_unsafe_item);
spin_unlock(&ci->i_unsafe_lock);
ceph_put_cap_refs(ci, CEPH_CAP_FILE_WR);
}
} }
if (file->f_flags & O_DIRECT) if (file->f_flags & O_DIRECT)
......
...@@ -36,6 +36,13 @@ static void ceph_vmtruncate_work(struct work_struct *work); ...@@ -36,6 +36,13 @@ static void ceph_vmtruncate_work(struct work_struct *work);
/* /*
* find or create an inode, given the ceph ino number * find or create an inode, given the ceph ino number
*/ */
static int ceph_set_ino_cb(struct inode *inode, void *data)
{
ceph_inode(inode)->i_vino = *(struct ceph_vino *)data;
inode->i_ino = ceph_vino_to_ino(*(struct ceph_vino *)data);
return 0;
}
struct inode *ceph_get_inode(struct super_block *sb, struct ceph_vino vino) struct inode *ceph_get_inode(struct super_block *sb, struct ceph_vino vino)
{ {
struct inode *inode; struct inode *inode;
...@@ -1030,9 +1037,6 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, ...@@ -1030,9 +1037,6 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
dout("fill_trace doing d_move %p -> %p\n", dout("fill_trace doing d_move %p -> %p\n",
req->r_old_dentry, dn); req->r_old_dentry, dn);
/* d_move screws up d_subdirs order */
ceph_i_clear(dir, CEPH_I_COMPLETE);
d_move(req->r_old_dentry, dn); d_move(req->r_old_dentry, dn);
dout(" src %p '%.*s' dst %p '%.*s'\n", dout(" src %p '%.*s' dst %p '%.*s'\n",
req->r_old_dentry, req->r_old_dentry,
...@@ -1044,12 +1048,15 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, ...@@ -1044,12 +1048,15 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
rehashing bug in vfs_rename_dir */ rehashing bug in vfs_rename_dir */
ceph_invalidate_dentry_lease(dn); ceph_invalidate_dentry_lease(dn);
/* take overwritten dentry's readdir offset */ /*
dout("dn %p gets %p offset %lld (old offset %lld)\n", * d_move() puts the renamed dentry at the end of
req->r_old_dentry, dn, ceph_dentry(dn)->offset, * d_subdirs. We need to assign it an appropriate
* directory offset so we can behave when holding
* I_COMPLETE.
*/
ceph_set_dentry_offset(req->r_old_dentry);
dout("dn %p gets new offset %lld\n", req->r_old_dentry,
ceph_dentry(req->r_old_dentry)->offset); ceph_dentry(req->r_old_dentry)->offset);
ceph_dentry(req->r_old_dentry)->offset =
ceph_dentry(dn)->offset;
dn = req->r_old_dentry; /* use old_dentry */ dn = req->r_old_dentry; /* use old_dentry */
in = dn->d_inode; in = dn->d_inode;
...@@ -1809,7 +1816,7 @@ int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry, ...@@ -1809,7 +1816,7 @@ int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry,
err = ceph_do_getattr(inode, CEPH_STAT_CAP_INODE_ALL); err = ceph_do_getattr(inode, CEPH_STAT_CAP_INODE_ALL);
if (!err) { if (!err) {
generic_fillattr(inode, stat); generic_fillattr(inode, stat);
stat->ino = inode->i_ino; stat->ino = ceph_translate_ino(inode->i_sb, inode->i_ino);
if (ceph_snap(inode) != CEPH_NOSNAP) if (ceph_snap(inode) != CEPH_NOSNAP)
stat->dev = ceph_snap(inode); stat->dev = ceph_snap(inode);
else else
......
...@@ -131,6 +131,7 @@ enum { ...@@ -131,6 +131,7 @@ enum {
Opt_rbytes, Opt_rbytes,
Opt_norbytes, Opt_norbytes,
Opt_noasyncreaddir, Opt_noasyncreaddir,
Opt_ino32,
}; };
static match_table_t fsopt_tokens = { static match_table_t fsopt_tokens = {
...@@ -150,6 +151,7 @@ static match_table_t fsopt_tokens = { ...@@ -150,6 +151,7 @@ static match_table_t fsopt_tokens = {
{Opt_rbytes, "rbytes"}, {Opt_rbytes, "rbytes"},
{Opt_norbytes, "norbytes"}, {Opt_norbytes, "norbytes"},
{Opt_noasyncreaddir, "noasyncreaddir"}, {Opt_noasyncreaddir, "noasyncreaddir"},
{Opt_ino32, "ino32"},
{-1, NULL} {-1, NULL}
}; };
...@@ -225,6 +227,9 @@ static int parse_fsopt_token(char *c, void *private) ...@@ -225,6 +227,9 @@ static int parse_fsopt_token(char *c, void *private)
case Opt_noasyncreaddir: case Opt_noasyncreaddir:
fsopt->flags |= CEPH_MOUNT_OPT_NOASYNCREADDIR; fsopt->flags |= CEPH_MOUNT_OPT_NOASYNCREADDIR;
break; break;
case Opt_ino32:
fsopt->flags |= CEPH_MOUNT_OPT_INO32;
break;
default: default:
BUG_ON(token); BUG_ON(token);
} }
...@@ -288,7 +293,7 @@ static int parse_mount_options(struct ceph_mount_options **pfsopt, ...@@ -288,7 +293,7 @@ static int parse_mount_options(struct ceph_mount_options **pfsopt,
fsopt->sb_flags = flags; fsopt->sb_flags = flags;
fsopt->flags = CEPH_MOUNT_OPT_DEFAULT; fsopt->flags = CEPH_MOUNT_OPT_DEFAULT;
fsopt->rsize = CEPH_MOUNT_RSIZE_DEFAULT; fsopt->rsize = CEPH_RSIZE_DEFAULT;
fsopt->snapdir_name = kstrdup(CEPH_SNAPDIRNAME_DEFAULT, GFP_KERNEL); fsopt->snapdir_name = kstrdup(CEPH_SNAPDIRNAME_DEFAULT, GFP_KERNEL);
fsopt->caps_wanted_delay_min = CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT; fsopt->caps_wanted_delay_min = CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT;
fsopt->caps_wanted_delay_max = CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT; fsopt->caps_wanted_delay_max = CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT;
...@@ -370,7 +375,7 @@ static int ceph_show_options(struct seq_file *m, struct vfsmount *mnt) ...@@ -370,7 +375,7 @@ static int ceph_show_options(struct seq_file *m, struct vfsmount *mnt)
if (fsopt->wsize) if (fsopt->wsize)
seq_printf(m, ",wsize=%d", fsopt->wsize); seq_printf(m, ",wsize=%d", fsopt->wsize);
if (fsopt->rsize != CEPH_MOUNT_RSIZE_DEFAULT) if (fsopt->rsize != CEPH_RSIZE_DEFAULT)
seq_printf(m, ",rsize=%d", fsopt->rsize); seq_printf(m, ",rsize=%d", fsopt->rsize);
if (fsopt->congestion_kb != default_congestion_kb()) if (fsopt->congestion_kb != default_congestion_kb())
seq_printf(m, ",write_congestion_kb=%d", fsopt->congestion_kb); seq_printf(m, ",write_congestion_kb=%d", fsopt->congestion_kb);
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#define CEPH_MOUNT_OPT_DIRSTAT (1<<4) /* `cat dirname` for stats */ #define CEPH_MOUNT_OPT_DIRSTAT (1<<4) /* `cat dirname` for stats */
#define CEPH_MOUNT_OPT_RBYTES (1<<5) /* dir st_bytes = rbytes */ #define CEPH_MOUNT_OPT_RBYTES (1<<5) /* dir st_bytes = rbytes */
#define CEPH_MOUNT_OPT_NOASYNCREADDIR (1<<7) /* no dcache readdir */ #define CEPH_MOUNT_OPT_NOASYNCREADDIR (1<<7) /* no dcache readdir */
#define CEPH_MOUNT_OPT_INO32 (1<<8) /* 32 bit inos */
#define CEPH_MOUNT_OPT_DEFAULT (CEPH_MOUNT_OPT_RBYTES) #define CEPH_MOUNT_OPT_DEFAULT (CEPH_MOUNT_OPT_RBYTES)
...@@ -35,6 +36,7 @@ ...@@ -35,6 +36,7 @@
#define ceph_test_mount_opt(fsc, opt) \ #define ceph_test_mount_opt(fsc, opt) \
(!!((fsc)->mount_options->flags & CEPH_MOUNT_OPT_##opt)) (!!((fsc)->mount_options->flags & CEPH_MOUNT_OPT_##opt))
#define CEPH_RSIZE_DEFAULT (512*1024) /* readahead */
#define CEPH_MAX_READDIR_DEFAULT 1024 #define CEPH_MAX_READDIR_DEFAULT 1024
#define CEPH_MAX_READDIR_BYTES_DEFAULT (512*1024) #define CEPH_MAX_READDIR_BYTES_DEFAULT (512*1024)
#define CEPH_SNAPDIRNAME_DEFAULT ".snap" #define CEPH_SNAPDIRNAME_DEFAULT ".snap"
...@@ -319,6 +321,16 @@ static inline struct ceph_inode_info *ceph_inode(struct inode *inode) ...@@ -319,6 +321,16 @@ static inline struct ceph_inode_info *ceph_inode(struct inode *inode)
return container_of(inode, struct ceph_inode_info, vfs_inode); return container_of(inode, struct ceph_inode_info, vfs_inode);
} }
static inline struct ceph_fs_client *ceph_inode_to_client(struct inode *inode)
{
return (struct ceph_fs_client *)inode->i_sb->s_fs_info;
}
static inline struct ceph_fs_client *ceph_sb_to_client(struct super_block *sb)
{
return (struct ceph_fs_client *)sb->s_fs_info;
}
static inline struct ceph_vino ceph_vino(struct inode *inode) static inline struct ceph_vino ceph_vino(struct inode *inode)
{ {
return ceph_inode(inode)->i_vino; return ceph_inode(inode)->i_vino;
...@@ -327,19 +339,49 @@ static inline struct ceph_vino ceph_vino(struct inode *inode) ...@@ -327,19 +339,49 @@ static inline struct ceph_vino ceph_vino(struct inode *inode)
/* /*
* ino_t is <64 bits on many architectures, blech. * ino_t is <64 bits on many architectures, blech.
* *
* don't include snap in ino hash, at least for now. * i_ino (kernel inode) st_ino (userspace)
* i386 32 32
* x86_64+ino32 64 32
* x86_64 64 64
*/
static inline u32 ceph_ino_to_ino32(ino_t ino)
{
ino ^= ino >> (sizeof(ino) * 8 - 32);
if (!ino)
ino = 1;
return ino;
}
/*
* kernel i_ino value
*/ */
static inline ino_t ceph_vino_to_ino(struct ceph_vino vino) static inline ino_t ceph_vino_to_ino(struct ceph_vino vino)
{ {
ino_t ino = (ino_t)vino.ino; /* ^ (vino.snap << 20); */ ino_t ino = (ino_t)vino.ino; /* ^ (vino.snap << 20); */
#if BITS_PER_LONG == 32 #if BITS_PER_LONG == 32
ino ^= vino.ino >> (sizeof(u64)-sizeof(ino_t)) * 8; ino = ceph_ino_to_ino32(ino);
if (!ino)
ino = 1;
#endif #endif
return ino; return ino;
} }
/*
* user-visible ino (stat, filldir)
*/
#if BITS_PER_LONG == 32
static inline ino_t ceph_translate_ino(struct super_block *sb, ino_t ino)
{
return ino;
}
#else
static inline ino_t ceph_translate_ino(struct super_block *sb, ino_t ino)
{
if (ceph_test_mount_opt(ceph_sb_to_client(sb), INO32))
ino = ceph_ino_to_ino32(ino);
return ino;
}
#endif
/* for printf-style formatting */ /* for printf-style formatting */
#define ceph_vinop(i) ceph_inode(i)->i_vino.ino, ceph_inode(i)->i_vino.snap #define ceph_vinop(i) ceph_inode(i)->i_vino.ino, ceph_inode(i)->i_vino.snap
...@@ -428,13 +470,6 @@ static inline loff_t ceph_make_fpos(unsigned frag, unsigned off) ...@@ -428,13 +470,6 @@ static inline loff_t ceph_make_fpos(unsigned frag, unsigned off)
return ((loff_t)frag << 32) | (loff_t)off; return ((loff_t)frag << 32) | (loff_t)off;
} }
static inline int ceph_set_ino_cb(struct inode *inode, void *data)
{
ceph_inode(inode)->i_vino = *(struct ceph_vino *)data;
inode->i_ino = ceph_vino_to_ino(*(struct ceph_vino *)data);
return 0;
}
/* /*
* caps helpers * caps helpers
*/ */
...@@ -503,15 +538,6 @@ extern void ceph_reservation_status(struct ceph_fs_client *client, ...@@ -503,15 +538,6 @@ extern void ceph_reservation_status(struct ceph_fs_client *client,
int *total, int *avail, int *used, int *total, int *avail, int *used,
int *reserved, int *min); int *reserved, int *min);
static inline struct ceph_fs_client *ceph_inode_to_client(struct inode *inode)
{
return (struct ceph_fs_client *)inode->i_sb->s_fs_info;
}
static inline struct ceph_fs_client *ceph_sb_to_client(struct super_block *sb)
{
return (struct ceph_fs_client *)sb->s_fs_info;
}
/* /*
......
...@@ -139,6 +139,15 @@ struct ceph_dir_layout { ...@@ -139,6 +139,15 @@ struct ceph_dir_layout {
#define CEPH_MSG_OSD_MAP 41 #define CEPH_MSG_OSD_MAP 41
#define CEPH_MSG_OSD_OP 42 #define CEPH_MSG_OSD_OP 42
#define CEPH_MSG_OSD_OPREPLY 43 #define CEPH_MSG_OSD_OPREPLY 43
#define CEPH_MSG_WATCH_NOTIFY 44
/* watch-notify operations */
enum {
WATCH_NOTIFY = 1, /* notifying watcher */
WATCH_NOTIFY_COMPLETE = 2, /* notifier notified when done */
};
/* pool operations */ /* pool operations */
enum { enum {
...@@ -213,6 +222,8 @@ struct ceph_client_mount { ...@@ -213,6 +222,8 @@ struct ceph_client_mount {
struct ceph_mon_request_header monhdr; struct ceph_mon_request_header monhdr;
} __attribute__ ((packed)); } __attribute__ ((packed));
#define CEPH_SUBSCRIBE_ONETIME 1 /* i want only 1 update after have */
struct ceph_mon_subscribe_item { struct ceph_mon_subscribe_item {
__le64 have_version; __le64 have; __le64 have_version; __le64 have;
__u8 onetime; __u8 onetime;
......
...@@ -71,7 +71,6 @@ struct ceph_options { ...@@ -71,7 +71,6 @@ struct ceph_options {
#define CEPH_OSD_TIMEOUT_DEFAULT 60 /* seconds */ #define CEPH_OSD_TIMEOUT_DEFAULT 60 /* seconds */
#define CEPH_OSD_KEEPALIVE_DEFAULT 5 #define CEPH_OSD_KEEPALIVE_DEFAULT 5
#define CEPH_OSD_IDLE_TTL_DEFAULT 60 #define CEPH_OSD_IDLE_TTL_DEFAULT 60
#define CEPH_MOUNT_RSIZE_DEFAULT (512*1024) /* readahead */
#define CEPH_MSG_MAX_FRONT_LEN (16*1024*1024) #define CEPH_MSG_MAX_FRONT_LEN (16*1024*1024)
#define CEPH_MSG_MAX_DATA_LEN (16*1024*1024) #define CEPH_MSG_MAX_DATA_LEN (16*1024*1024)
......
...@@ -32,6 +32,7 @@ struct ceph_osd { ...@@ -32,6 +32,7 @@ struct ceph_osd {
struct rb_node o_node; struct rb_node o_node;
struct ceph_connection o_con; struct ceph_connection o_con;
struct list_head o_requests; struct list_head o_requests;
struct list_head o_linger_requests;
struct list_head o_osd_lru; struct list_head o_osd_lru;
struct ceph_authorizer *o_authorizer; struct ceph_authorizer *o_authorizer;
void *o_authorizer_buf, *o_authorizer_reply_buf; void *o_authorizer_buf, *o_authorizer_reply_buf;
...@@ -47,6 +48,8 @@ struct ceph_osd_request { ...@@ -47,6 +48,8 @@ struct ceph_osd_request {
struct rb_node r_node; struct rb_node r_node;
struct list_head r_req_lru_item; struct list_head r_req_lru_item;
struct list_head r_osd_item; struct list_head r_osd_item;
struct list_head r_linger_item;
struct list_head r_linger_osd;
struct ceph_osd *r_osd; struct ceph_osd *r_osd;
struct ceph_pg r_pgid; struct ceph_pg r_pgid;
int r_pg_osds[CEPH_PG_MAX_SIZE]; int r_pg_osds[CEPH_PG_MAX_SIZE];
...@@ -59,6 +62,7 @@ struct ceph_osd_request { ...@@ -59,6 +62,7 @@ struct ceph_osd_request {
int r_flags; /* any additional flags for the osd */ int r_flags; /* any additional flags for the osd */
u32 r_sent; /* >0 if r_request is sending/sent */ u32 r_sent; /* >0 if r_request is sending/sent */
int r_got_reply; int r_got_reply;
int r_linger;
struct ceph_osd_client *r_osdc; struct ceph_osd_client *r_osdc;
struct kref r_kref; struct kref r_kref;
...@@ -74,7 +78,6 @@ struct ceph_osd_request { ...@@ -74,7 +78,6 @@ struct ceph_osd_request {
char r_oid[40]; /* object name */ char r_oid[40]; /* object name */
int r_oid_len; int r_oid_len;
unsigned long r_stamp; /* send OR check time */ unsigned long r_stamp; /* send OR check time */
bool r_resend; /* msg send failed, needs retry */
struct ceph_file_layout r_file_layout; struct ceph_file_layout r_file_layout;
struct ceph_snap_context *r_snapc; /* snap context for writes */ struct ceph_snap_context *r_snapc; /* snap context for writes */
...@@ -90,6 +93,26 @@ struct ceph_osd_request { ...@@ -90,6 +93,26 @@ struct ceph_osd_request {
struct ceph_pagelist *r_trail; /* trailing part of the data */ struct ceph_pagelist *r_trail; /* trailing part of the data */
}; };
struct ceph_osd_event {
u64 cookie;
int one_shot;
struct ceph_osd_client *osdc;
void (*cb)(u64, u64, u8, void *);
void *data;
struct rb_node node;
struct list_head osd_node;
struct kref kref;
struct completion completion;
};
struct ceph_osd_event_work {
struct work_struct work;
struct ceph_osd_event *event;
u64 ver;
u64 notify_id;
u8 opcode;
};
struct ceph_osd_client { struct ceph_osd_client {
struct ceph_client *client; struct ceph_client *client;
...@@ -104,7 +127,10 @@ struct ceph_osd_client { ...@@ -104,7 +127,10 @@ struct ceph_osd_client {
u64 timeout_tid; /* tid of timeout triggering rq */ u64 timeout_tid; /* tid of timeout triggering rq */
u64 last_tid; /* tid of last request */ u64 last_tid; /* tid of last request */
struct rb_root requests; /* pending requests */ struct rb_root requests; /* pending requests */
struct list_head req_lru; /* pending requests lru */ struct list_head req_lru; /* in-flight lru */
struct list_head req_unsent; /* unsent/need-resend queue */
struct list_head req_notarget; /* map to no osd */
struct list_head req_linger; /* lingering requests */
int num_requests; int num_requests;
struct delayed_work timeout_work; struct delayed_work timeout_work;
struct delayed_work osds_timeout_work; struct delayed_work osds_timeout_work;
...@@ -116,6 +142,12 @@ struct ceph_osd_client { ...@@ -116,6 +142,12 @@ struct ceph_osd_client {
struct ceph_msgpool msgpool_op; struct ceph_msgpool msgpool_op;
struct ceph_msgpool msgpool_op_reply; struct ceph_msgpool msgpool_op_reply;
spinlock_t event_lock;
struct rb_root event_tree;
u64 event_count;
struct workqueue_struct *notify_wq;
}; };
struct ceph_osd_req_op { struct ceph_osd_req_op {
...@@ -150,6 +182,13 @@ struct ceph_osd_req_op { ...@@ -150,6 +182,13 @@ struct ceph_osd_req_op {
struct { struct {
u64 snapid; u64 snapid;
} snap; } snap;
struct {
u64 cookie;
u64 ver;
__u8 flag;
u32 prot_ver;
u32 timeout;
} watch;
}; };
u32 payload_len; u32 payload_len;
}; };
...@@ -198,6 +237,11 @@ extern struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *, ...@@ -198,6 +237,11 @@ extern struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *,
bool use_mempool, int num_reply, bool use_mempool, int num_reply,
int page_align); int page_align);
extern void ceph_osdc_set_request_linger(struct ceph_osd_client *osdc,
struct ceph_osd_request *req);
extern void ceph_osdc_unregister_linger_request(struct ceph_osd_client *osdc,
struct ceph_osd_request *req);
static inline void ceph_osdc_get_request(struct ceph_osd_request *req) static inline void ceph_osdc_get_request(struct ceph_osd_request *req)
{ {
kref_get(&req->r_kref); kref_get(&req->r_kref);
...@@ -233,5 +277,14 @@ extern int ceph_osdc_writepages(struct ceph_osd_client *osdc, ...@@ -233,5 +277,14 @@ extern int ceph_osdc_writepages(struct ceph_osd_client *osdc,
struct page **pages, int nr_pages, struct page **pages, int nr_pages,
int flags, int do_sync, bool nofail); int flags, int do_sync, bool nofail);
/* watch/notify events */
extern int ceph_osdc_create_event(struct ceph_osd_client *osdc,
void (*event_cb)(u64, u64, u8, void *),
int one_shot, void *data,
struct ceph_osd_event **pevent);
extern void ceph_osdc_cancel_event(struct ceph_osd_event *event);
extern int ceph_osdc_wait_event(struct ceph_osd_event *event,
unsigned long timeout);
extern void ceph_osdc_put_event(struct ceph_osd_event *event);
#endif #endif
...@@ -12,9 +12,9 @@ ...@@ -12,9 +12,9 @@
* osdmap encoding versions * osdmap encoding versions
*/ */
#define CEPH_OSDMAP_INC_VERSION 5 #define CEPH_OSDMAP_INC_VERSION 5
#define CEPH_OSDMAP_INC_VERSION_EXT 5 #define CEPH_OSDMAP_INC_VERSION_EXT 6
#define CEPH_OSDMAP_VERSION 5 #define CEPH_OSDMAP_VERSION 5
#define CEPH_OSDMAP_VERSION_EXT 5 #define CEPH_OSDMAP_VERSION_EXT 6
/* /*
* fs id * fs id
...@@ -181,9 +181,17 @@ enum { ...@@ -181,9 +181,17 @@ enum {
/* read */ /* read */
CEPH_OSD_OP_READ = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_DATA | 1, CEPH_OSD_OP_READ = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_DATA | 1,
CEPH_OSD_OP_STAT = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_DATA | 2, CEPH_OSD_OP_STAT = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_DATA | 2,
CEPH_OSD_OP_MAPEXT = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_DATA | 3,
/* fancy read */ /* fancy read */
CEPH_OSD_OP_MASKTRUNC = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_DATA | 4, CEPH_OSD_OP_MASKTRUNC = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_DATA | 4,
CEPH_OSD_OP_SPARSE_READ = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_DATA | 5,
CEPH_OSD_OP_NOTIFY = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_DATA | 6,
CEPH_OSD_OP_NOTIFY_ACK = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_DATA | 7,
/* versioning */
CEPH_OSD_OP_ASSERT_VER = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_DATA | 8,
/* write */ /* write */
CEPH_OSD_OP_WRITE = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 1, CEPH_OSD_OP_WRITE = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 1,
...@@ -205,6 +213,8 @@ enum { ...@@ -205,6 +213,8 @@ enum {
CEPH_OSD_OP_CREATE = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 13, CEPH_OSD_OP_CREATE = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 13,
CEPH_OSD_OP_ROLLBACK= CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 14, CEPH_OSD_OP_ROLLBACK= CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 14,
CEPH_OSD_OP_WATCH = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 15,
/** attrs **/ /** attrs **/
/* read */ /* read */
CEPH_OSD_OP_GETXATTR = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_ATTR | 1, CEPH_OSD_OP_GETXATTR = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_ATTR | 1,
...@@ -223,6 +233,9 @@ enum { ...@@ -223,6 +233,9 @@ enum {
CEPH_OSD_OP_BALANCEREADS = CEPH_OSD_OP_MODE_SUB | 3, CEPH_OSD_OP_BALANCEREADS = CEPH_OSD_OP_MODE_SUB | 3,
CEPH_OSD_OP_UNBALANCEREADS = CEPH_OSD_OP_MODE_SUB | 4, CEPH_OSD_OP_UNBALANCEREADS = CEPH_OSD_OP_MODE_SUB | 4,
CEPH_OSD_OP_SCRUB = CEPH_OSD_OP_MODE_SUB | 5, CEPH_OSD_OP_SCRUB = CEPH_OSD_OP_MODE_SUB | 5,
CEPH_OSD_OP_SCRUB_RESERVE = CEPH_OSD_OP_MODE_SUB | 6,
CEPH_OSD_OP_SCRUB_UNRESERVE = CEPH_OSD_OP_MODE_SUB | 7,
CEPH_OSD_OP_SCRUB_STOP = CEPH_OSD_OP_MODE_SUB | 8,
/** lock **/ /** lock **/
CEPH_OSD_OP_WRLOCK = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_LOCK | 1, CEPH_OSD_OP_WRLOCK = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_LOCK | 1,
...@@ -328,6 +341,8 @@ enum { ...@@ -328,6 +341,8 @@ enum {
CEPH_OSD_CMPXATTR_MODE_U64 = 2 CEPH_OSD_CMPXATTR_MODE_U64 = 2
}; };
#define RADOS_NOTIFY_VER 1
/* /*
* an individual object operation. each may be accompanied by some data * an individual object operation. each may be accompanied by some data
* payload * payload
...@@ -359,7 +374,12 @@ struct ceph_osd_op { ...@@ -359,7 +374,12 @@ struct ceph_osd_op {
struct { struct {
__le64 snapid; __le64 snapid;
} __attribute__ ((packed)) snap; } __attribute__ ((packed)) snap;
}; struct {
__le64 cookie;
__le64 ver;
__u8 flag; /* 0 = unwatch, 1 = watch */
} __attribute__ ((packed)) watch;
};
__le32 payload_len; __le32 payload_len;
} __attribute__ ((packed)); } __attribute__ ((packed));
...@@ -402,4 +422,5 @@ struct ceph_osd_reply_head { ...@@ -402,4 +422,5 @@ struct ceph_osd_reply_head {
} __attribute__ ((packed)); } __attribute__ ((packed));
#endif #endif
...@@ -78,8 +78,10 @@ int ceph_unarmor(char *dst, const char *src, const char *end) ...@@ -78,8 +78,10 @@ int ceph_unarmor(char *dst, const char *src, const char *end)
while (src < end) { while (src < end) {
int a, b, c, d; int a, b, c, d;
if (src < end && src[0] == '\n') if (src[0] == '\n') {
src++; src++;
continue;
}
if (src + 4 > end) if (src + 4 > end)
return -EINVAL; return -EINVAL;
a = decode_bits(src[0]); a = decode_bits(src[0]);
......
...@@ -62,6 +62,7 @@ const char *ceph_msg_type_name(int type) ...@@ -62,6 +62,7 @@ const char *ceph_msg_type_name(int type)
case CEPH_MSG_OSD_MAP: return "osd_map"; case CEPH_MSG_OSD_MAP: return "osd_map";
case CEPH_MSG_OSD_OP: return "osd_op"; case CEPH_MSG_OSD_OP: return "osd_op";
case CEPH_MSG_OSD_OPREPLY: return "osd_opreply"; case CEPH_MSG_OSD_OPREPLY: return "osd_opreply";
case CEPH_MSG_WATCH_NOTIFY: return "watch_notify";
default: return "unknown"; default: return "unknown";
} }
} }
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment