diff options
Diffstat (limited to 'fs/ceph')
-rw-r--r-- | fs/ceph/caps.c | 43 | ||||
-rw-r--r-- | fs/ceph/dir.c | 5 | ||||
-rw-r--r-- | fs/ceph/inode.c | 10 | ||||
-rw-r--r-- | fs/ceph/mds_client.c | 10 | ||||
-rw-r--r-- | fs/ceph/snap.c | 14 | ||||
-rw-r--r-- | fs/ceph/super.c | 2 | ||||
-rw-r--r-- | fs/ceph/super.h | 1 | ||||
-rw-r--r-- | fs/ceph/xattr.c | 3 |
8 files changed, 69 insertions, 19 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 60d27bc9eb83..6b61ded701e1 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -1560,9 +1560,10 @@ retry_locked: | |||
1560 | /* NOTE: no side-effects allowed, until we take s_mutex */ | 1560 | /* NOTE: no side-effects allowed, until we take s_mutex */ |
1561 | 1561 | ||
1562 | revoking = cap->implemented & ~cap->issued; | 1562 | revoking = cap->implemented & ~cap->issued; |
1563 | if (revoking) | 1563 | dout(" mds%d cap %p issued %s implemented %s revoking %s\n", |
1564 | dout(" mds%d revoking %s\n", cap->mds, | 1564 | cap->mds, cap, ceph_cap_string(cap->issued), |
1565 | ceph_cap_string(revoking)); | 1565 | ceph_cap_string(cap->implemented), |
1566 | ceph_cap_string(revoking)); | ||
1566 | 1567 | ||
1567 | if (cap == ci->i_auth_cap && | 1568 | if (cap == ci->i_auth_cap && |
1568 | (cap->issued & CEPH_CAP_FILE_WR)) { | 1569 | (cap->issued & CEPH_CAP_FILE_WR)) { |
@@ -1658,6 +1659,8 @@ ack: | |||
1658 | 1659 | ||
1659 | if (cap == ci->i_auth_cap && ci->i_dirty_caps) | 1660 | if (cap == ci->i_auth_cap && ci->i_dirty_caps) |
1660 | flushing = __mark_caps_flushing(inode, session); | 1661 | flushing = __mark_caps_flushing(inode, session); |
1662 | else | ||
1663 | flushing = 0; | ||
1661 | 1664 | ||
1662 | mds = cap->mds; /* remember mds, so we don't repeat */ | 1665 | mds = cap->mds; /* remember mds, so we don't repeat */ |
1663 | sent++; | 1666 | sent++; |
@@ -1940,6 +1943,35 @@ void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc, | |||
1940 | } | 1943 | } |
1941 | } | 1944 | } |
1942 | 1945 | ||
1946 | static void kick_flushing_inode_caps(struct ceph_mds_client *mdsc, | ||
1947 | struct ceph_mds_session *session, | ||
1948 | struct inode *inode) | ||
1949 | { | ||
1950 | struct ceph_inode_info *ci = ceph_inode(inode); | ||
1951 | struct ceph_cap *cap; | ||
1952 | int delayed = 0; | ||
1953 | |||
1954 | spin_lock(&inode->i_lock); | ||
1955 | cap = ci->i_auth_cap; | ||
1956 | dout("kick_flushing_inode_caps %p flushing %s flush_seq %lld\n", inode, | ||
1957 | ceph_cap_string(ci->i_flushing_caps), ci->i_cap_flush_seq); | ||
1958 | __ceph_flush_snaps(ci, &session, 1); | ||
1959 | if (ci->i_flushing_caps) { | ||
1960 | delayed = __send_cap(mdsc, cap, CEPH_CAP_OP_FLUSH, | ||
1961 | __ceph_caps_used(ci), | ||
1962 | __ceph_caps_wanted(ci), | ||
1963 | cap->issued | cap->implemented, | ||
1964 | ci->i_flushing_caps, NULL); | ||
1965 | if (delayed) { | ||
1966 | spin_lock(&inode->i_lock); | ||
1967 | __cap_delay_requeue(mdsc, ci); | ||
1968 | spin_unlock(&inode->i_lock); | ||
1969 | } | ||
1970 | } else { | ||
1971 | spin_unlock(&inode->i_lock); | ||
1972 | } | ||
1973 | } | ||
1974 | |||
1943 | 1975 | ||
1944 | /* | 1976 | /* |
1945 | * Take references to capabilities we hold, so that we don't release | 1977 | * Take references to capabilities we hold, so that we don't release |
@@ -2687,7 +2719,7 @@ static void handle_cap_import(struct ceph_mds_client *mdsc, | |||
2687 | ceph_add_cap(inode, session, cap_id, -1, | 2719 | ceph_add_cap(inode, session, cap_id, -1, |
2688 | issued, wanted, seq, mseq, realmino, CEPH_CAP_FLAG_AUTH, | 2720 | issued, wanted, seq, mseq, realmino, CEPH_CAP_FLAG_AUTH, |
2689 | NULL /* no caps context */); | 2721 | NULL /* no caps context */); |
2690 | try_flush_caps(inode, session, NULL); | 2722 | kick_flushing_inode_caps(mdsc, session, inode); |
2691 | up_read(&mdsc->snap_rwsem); | 2723 | up_read(&mdsc->snap_rwsem); |
2692 | 2724 | ||
2693 | /* make sure we re-request max_size, if necessary */ | 2725 | /* make sure we re-request max_size, if necessary */ |
@@ -2785,8 +2817,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, | |||
2785 | case CEPH_CAP_OP_IMPORT: | 2817 | case CEPH_CAP_OP_IMPORT: |
2786 | handle_cap_import(mdsc, inode, h, session, | 2818 | handle_cap_import(mdsc, inode, h, session, |
2787 | snaptrace, snaptrace_len); | 2819 | snaptrace, snaptrace_len); |
2788 | ceph_check_caps(ceph_inode(inode), CHECK_CAPS_NODELAY, | 2820 | ceph_check_caps(ceph_inode(inode), 0, session); |
2789 | session); | ||
2790 | goto done_unlocked; | 2821 | goto done_unlocked; |
2791 | } | 2822 | } |
2792 | 2823 | ||
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 0bc68de8edd7..f0aef787a102 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -60,6 +60,7 @@ int ceph_init_dentry(struct dentry *dentry) | |||
60 | } | 60 | } |
61 | di->dentry = dentry; | 61 | di->dentry = dentry; |
62 | di->lease_session = NULL; | 62 | di->lease_session = NULL; |
63 | di->parent_inode = igrab(dentry->d_parent->d_inode); | ||
63 | dentry->d_fsdata = di; | 64 | dentry->d_fsdata = di; |
64 | dentry->d_time = jiffies; | 65 | dentry->d_time = jiffies; |
65 | ceph_dentry_lru_add(dentry); | 66 | ceph_dentry_lru_add(dentry); |
@@ -1033,7 +1034,7 @@ static void ceph_dentry_release(struct dentry *dentry) | |||
1033 | u64 snapid = CEPH_NOSNAP; | 1034 | u64 snapid = CEPH_NOSNAP; |
1034 | 1035 | ||
1035 | if (!IS_ROOT(dentry)) { | 1036 | if (!IS_ROOT(dentry)) { |
1036 | parent_inode = dentry->d_parent->d_inode; | 1037 | parent_inode = di->parent_inode; |
1037 | if (parent_inode) | 1038 | if (parent_inode) |
1038 | snapid = ceph_snap(parent_inode); | 1039 | snapid = ceph_snap(parent_inode); |
1039 | } | 1040 | } |
@@ -1058,6 +1059,8 @@ static void ceph_dentry_release(struct dentry *dentry) | |||
1058 | kmem_cache_free(ceph_dentry_cachep, di); | 1059 | kmem_cache_free(ceph_dentry_cachep, di); |
1059 | dentry->d_fsdata = NULL; | 1060 | dentry->d_fsdata = NULL; |
1060 | } | 1061 | } |
1062 | if (parent_inode) | ||
1063 | iput(parent_inode); | ||
1061 | } | 1064 | } |
1062 | 1065 | ||
1063 | static int ceph_snapdir_d_revalidate(struct dentry *dentry, | 1066 | static int ceph_snapdir_d_revalidate(struct dentry *dentry, |
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index e835eff551e3..5625463aa479 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
@@ -710,10 +710,6 @@ static int fill_inode(struct inode *inode, | |||
710 | ci->i_ceph_flags |= CEPH_I_COMPLETE; | 710 | ci->i_ceph_flags |= CEPH_I_COMPLETE; |
711 | ci->i_max_offset = 2; | 711 | ci->i_max_offset = 2; |
712 | } | 712 | } |
713 | |||
714 | /* it may be better to set st_size in getattr instead? */ | ||
715 | if (ceph_test_mount_opt(ceph_sb_to_client(inode->i_sb), RBYTES)) | ||
716 | inode->i_size = ci->i_rbytes; | ||
717 | break; | 713 | break; |
718 | default: | 714 | default: |
719 | pr_err("fill_inode %llx.%llx BAD mode 0%o\n", | 715 | pr_err("fill_inode %llx.%llx BAD mode 0%o\n", |
@@ -1819,7 +1815,11 @@ int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
1819 | else | 1815 | else |
1820 | stat->dev = 0; | 1816 | stat->dev = 0; |
1821 | if (S_ISDIR(inode->i_mode)) { | 1817 | if (S_ISDIR(inode->i_mode)) { |
1822 | stat->size = ci->i_rbytes; | 1818 | if (ceph_test_mount_opt(ceph_sb_to_client(inode->i_sb), |
1819 | RBYTES)) | ||
1820 | stat->size = ci->i_rbytes; | ||
1821 | else | ||
1822 | stat->size = ci->i_files + ci->i_subdirs; | ||
1823 | stat->blocks = 0; | 1823 | stat->blocks = 0; |
1824 | stat->blksize = 65536; | 1824 | stat->blksize = 65536; |
1825 | } | 1825 | } |
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 1e30d194a8e3..a1ee8fa3a8e7 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -693,9 +693,11 @@ static int __choose_mds(struct ceph_mds_client *mdsc, | |||
693 | dout("choose_mds %p %llx.%llx " | 693 | dout("choose_mds %p %llx.%llx " |
694 | "frag %u mds%d (%d/%d)\n", | 694 | "frag %u mds%d (%d/%d)\n", |
695 | inode, ceph_vinop(inode), | 695 | inode, ceph_vinop(inode), |
696 | frag.frag, frag.mds, | 696 | frag.frag, mds, |
697 | (int)r, frag.ndist); | 697 | (int)r, frag.ndist); |
698 | return mds; | 698 | if (ceph_mdsmap_get_state(mdsc->mdsmap, mds) >= |
699 | CEPH_MDS_STATE_ACTIVE) | ||
700 | return mds; | ||
699 | } | 701 | } |
700 | 702 | ||
701 | /* since this file/dir wasn't known to be | 703 | /* since this file/dir wasn't known to be |
@@ -708,7 +710,9 @@ static int __choose_mds(struct ceph_mds_client *mdsc, | |||
708 | dout("choose_mds %p %llx.%llx " | 710 | dout("choose_mds %p %llx.%llx " |
709 | "frag %u mds%d (auth)\n", | 711 | "frag %u mds%d (auth)\n", |
710 | inode, ceph_vinop(inode), frag.frag, mds); | 712 | inode, ceph_vinop(inode), frag.frag, mds); |
711 | return mds; | 713 | if (ceph_mdsmap_get_state(mdsc->mdsmap, mds) >= |
714 | CEPH_MDS_STATE_ACTIVE) | ||
715 | return mds; | ||
712 | } | 716 | } |
713 | } | 717 | } |
714 | } | 718 | } |
diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index 39c243acd062..f40b9139e437 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c | |||
@@ -584,10 +584,14 @@ static void queue_realm_cap_snaps(struct ceph_snap_realm *realm) | |||
584 | if (lastinode) | 584 | if (lastinode) |
585 | iput(lastinode); | 585 | iput(lastinode); |
586 | 586 | ||
587 | dout("queue_realm_cap_snaps %p %llx children\n", realm, realm->ino); | 587 | list_for_each_entry(child, &realm->children, child_item) { |
588 | list_for_each_entry(child, &realm->children, child_item) | 588 | dout("queue_realm_cap_snaps %p %llx queue child %p %llx\n", |
589 | queue_realm_cap_snaps(child); | 589 | realm, realm->ino, child, child->ino); |
590 | list_del_init(&child->dirty_item); | ||
591 | list_add(&child->dirty_item, &realm->dirty_item); | ||
592 | } | ||
590 | 593 | ||
594 | list_del_init(&realm->dirty_item); | ||
591 | dout("queue_realm_cap_snaps %p %llx done\n", realm, realm->ino); | 595 | dout("queue_realm_cap_snaps %p %llx done\n", realm, realm->ino); |
592 | } | 596 | } |
593 | 597 | ||
@@ -683,7 +687,9 @@ more: | |||
683 | * queue cap snaps _after_ we've built the new snap contexts, | 687 | * queue cap snaps _after_ we've built the new snap contexts, |
684 | * so that i_head_snapc can be set appropriately. | 688 | * so that i_head_snapc can be set appropriately. |
685 | */ | 689 | */ |
686 | list_for_each_entry(realm, &dirty_realms, dirty_item) { | 690 | while (!list_empty(&dirty_realms)) { |
691 | realm = list_first_entry(&dirty_realms, struct ceph_snap_realm, | ||
692 | dirty_item); | ||
687 | queue_realm_cap_snaps(realm); | 693 | queue_realm_cap_snaps(realm); |
688 | } | 694 | } |
689 | 695 | ||
diff --git a/fs/ceph/super.c b/fs/ceph/super.c index bf6f0f34082a..9c5085465a63 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c | |||
@@ -290,6 +290,8 @@ static int parse_mount_options(struct ceph_mount_options **pfsopt, | |||
290 | 290 | ||
291 | fsopt->rsize = CEPH_MOUNT_RSIZE_DEFAULT; | 291 | fsopt->rsize = CEPH_MOUNT_RSIZE_DEFAULT; |
292 | fsopt->snapdir_name = kstrdup(CEPH_SNAPDIRNAME_DEFAULT, GFP_KERNEL); | 292 | fsopt->snapdir_name = kstrdup(CEPH_SNAPDIRNAME_DEFAULT, GFP_KERNEL); |
293 | fsopt->caps_wanted_delay_min = CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT; | ||
294 | fsopt->caps_wanted_delay_max = CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT; | ||
293 | fsopt->cap_release_safety = CEPH_CAP_RELEASE_SAFETY_DEFAULT; | 295 | fsopt->cap_release_safety = CEPH_CAP_RELEASE_SAFETY_DEFAULT; |
294 | fsopt->max_readdir = CEPH_MAX_READDIR_DEFAULT; | 296 | fsopt->max_readdir = CEPH_MAX_READDIR_DEFAULT; |
295 | fsopt->max_readdir_bytes = CEPH_MAX_READDIR_BYTES_DEFAULT; | 297 | fsopt->max_readdir_bytes = CEPH_MAX_READDIR_BYTES_DEFAULT; |
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 20b907d76ae2..88fcaa21b801 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
@@ -207,6 +207,7 @@ struct ceph_dentry_info { | |||
207 | struct dentry *dentry; | 207 | struct dentry *dentry; |
208 | u64 time; | 208 | u64 time; |
209 | u64 offset; | 209 | u64 offset; |
210 | struct inode *parent_inode; | ||
210 | }; | 211 | }; |
211 | 212 | ||
212 | struct ceph_inode_xattrs_info { | 213 | struct ceph_inode_xattrs_info { |
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 6e12a6ba5f79..8c9eba6ef9df 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c | |||
@@ -219,6 +219,7 @@ static struct ceph_inode_xattr *__get_xattr(struct ceph_inode_info *ci, | |||
219 | struct rb_node **p; | 219 | struct rb_node **p; |
220 | struct rb_node *parent = NULL; | 220 | struct rb_node *parent = NULL; |
221 | struct ceph_inode_xattr *xattr = NULL; | 221 | struct ceph_inode_xattr *xattr = NULL; |
222 | int name_len = strlen(name); | ||
222 | int c; | 223 | int c; |
223 | 224 | ||
224 | p = &ci->i_xattrs.index.rb_node; | 225 | p = &ci->i_xattrs.index.rb_node; |
@@ -226,6 +227,8 @@ static struct ceph_inode_xattr *__get_xattr(struct ceph_inode_info *ci, | |||
226 | parent = *p; | 227 | parent = *p; |
227 | xattr = rb_entry(parent, struct ceph_inode_xattr, node); | 228 | xattr = rb_entry(parent, struct ceph_inode_xattr, node); |
228 | c = strncmp(name, xattr->name, xattr->name_len); | 229 | c = strncmp(name, xattr->name, xattr->name_len); |
230 | if (c == 0 && name_len > xattr->name_len) | ||
231 | c = 1; | ||
229 | if (c < 0) | 232 | if (c < 0) |
230 | p = &(*p)->rb_left; | 233 | p = &(*p)->rb_left; |
231 | else if (c > 0) | 234 | else if (c > 0) |