Skip to content

Commit 524d0c6

Browse files
committed
Merge tag 'ceph-for-6.1-rc1' of https://github.com/ceph/ceph-client
Pull ceph updates from Ilya Dryomov: "A quiet round this time: several assorted filesystem fixes, the most noteworthy one being some additional wakeups in cap handling code, and a messenger cleanup" * tag 'ceph-for-6.1-rc1' of https://github.com/ceph/ceph-client: ceph: remove Sage's git tree from documentation ceph: fix incorrectly showing the .snap size for stat ceph: fail the open_by_handle_at() if the dentry is being unlinked ceph: increment i_version when doing a setattr with caps ceph: Use kcalloc for allocating multiple elements ceph: no need to wait for transition RDCACHE|RD -> RD ceph: fail the request if the peer MDS doesn't support getvxattr op ceph: wake up the waiters if any new caps comes libceph: drop last_piece flag from ceph_msg_data_cursor
2 parents 66b8345 + 71cf0c1 commit 524d0c6

File tree

10 files changed

+64
-52
lines changed

10 files changed

+64
-52
lines changed

Documentation/filesystems/ceph.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,6 @@ For more information on Ceph, see the home page at
203203

204204
The Linux kernel client source tree is available at
205205
- https://github.com/ceph/ceph-client.git
206-
- git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client.git
207206

208207
and the source for the full system is at
209208
https://github.com/ceph/ceph.git

fs/ceph/caps.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,7 @@ void ceph_add_cap(struct inode *inode,
754754
cap->issue_seq = seq;
755755
cap->mseq = mseq;
756756
cap->cap_gen = gen;
757+
wake_up_all(&ci->i_cap_wq);
757758
}
758759

759760
/*
@@ -2285,7 +2286,7 @@ static int flush_mdlog_and_wait_inode_unsafe_requests(struct inode *inode)
22852286
struct ceph_mds_request *req;
22862287
int i;
22872288

2288-
sessions = kzalloc(max_sessions * sizeof(s), GFP_KERNEL);
2289+
sessions = kcalloc(max_sessions, sizeof(s), GFP_KERNEL);
22892290
if (!sessions) {
22902291
err = -ENOMEM;
22912292
goto out;
@@ -2759,13 +2760,17 @@ static int try_get_cap_refs(struct inode *inode, int need, int want,
27592760
* on transition from wanted -> needed caps. This is needed
27602761
* for WRBUFFER|WR -> WR to avoid a new WR sync write from
27612762
* going before a prior buffered writeback happens.
2763+
*
2764+
* For RDCACHE|RD -> RD, there is not need to wait and we can
2765+
* just exclude the revoking caps and force to sync read.
27622766
*/
27632767
int not = want & ~(have & need);
27642768
int revoking = implemented & ~have;
2769+
int exclude = revoking & not;
27652770
dout("get_cap_refs %p have %s but not %s (revoking %s)\n",
27662771
inode, ceph_cap_string(have), ceph_cap_string(not),
27672772
ceph_cap_string(revoking));
2768-
if ((revoking & not) == 0) {
2773+
if (!exclude || !(exclude & CEPH_CAP_FILE_BUFFER)) {
27692774
if (!snap_rwsem_locked &&
27702775
!ci->i_head_snapc &&
27712776
(need & CEPH_CAP_FILE_WR)) {
@@ -2787,7 +2792,7 @@ static int try_get_cap_refs(struct inode *inode, int need, int want,
27872792
snap_rwsem_locked = true;
27882793
}
27892794
if ((have & want) == want)
2790-
*got = need | want;
2795+
*got = need | (want & ~exclude);
27912796
else
27922797
*got = need;
27932798
ceph_take_cap_refs(ci, *got, true);
@@ -3550,6 +3555,9 @@ static void handle_cap_grant(struct inode *inode,
35503555
check_caps = 1; /* check auth cap only */
35513556
else
35523557
check_caps = 2; /* check all caps */
3558+
/* If there is new caps, try to wake up the waiters */
3559+
if (~cap->issued & newcaps)
3560+
wake = true;
35533561
cap->issued = newcaps;
35543562
cap->implemented |= newcaps;
35553563
} else if (cap->issued == newcaps) {

fs/ceph/export.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ struct inode *ceph_lookup_inode(struct super_block *sb, u64 ino)
181181
static struct dentry *__fh_to_dentry(struct super_block *sb, u64 ino)
182182
{
183183
struct inode *inode = __lookup_inode(sb, ino);
184+
struct ceph_inode_info *ci = ceph_inode(inode);
184185
int err;
185186

186187
if (IS_ERR(inode))
@@ -192,7 +193,7 @@ static struct dentry *__fh_to_dentry(struct super_block *sb, u64 ino)
192193
return ERR_PTR(err);
193194
}
194195
/* -ESTALE if inode as been unlinked and no file is open */
195-
if ((inode->i_nlink == 0) && (atomic_read(&inode->i_count) == 1)) {
196+
if ((inode->i_nlink == 0) && !__ceph_is_file_opened(ci)) {
196197
iput(inode);
197198
return ERR_PTR(-ESTALE);
198199
}

fs/ceph/inode.c

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2192,6 +2192,7 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
21922192
inode_dirty_flags = __ceph_mark_dirty_caps(ci, dirtied,
21932193
&prealloc_cf);
21942194
inode->i_ctime = attr->ia_ctime;
2195+
inode_inc_iversion_raw(inode);
21952196
}
21962197

21972198
release &= issued;
@@ -2356,6 +2357,7 @@ int ceph_do_getvxattr(struct inode *inode, const char *name, void *value,
23562357
goto out;
23572358
}
23582359

2360+
req->r_feature_needed = CEPHFS_FEATURE_OP_GETVXATTR;
23592361
req->r_path2 = kstrdup(name, GFP_NOFS);
23602362
if (!req->r_path2) {
23612363
err = -ENOMEM;
@@ -2447,6 +2449,7 @@ int ceph_getattr(struct user_namespace *mnt_userns, const struct path *path,
24472449
struct kstat *stat, u32 request_mask, unsigned int flags)
24482450
{
24492451
struct inode *inode = d_inode(path->dentry);
2452+
struct super_block *sb = inode->i_sb;
24502453
struct ceph_inode_info *ci = ceph_inode(inode);
24512454
u32 valid_mask = STATX_BASIC_STATS;
24522455
int err = 0;
@@ -2476,16 +2479,34 @@ int ceph_getattr(struct user_namespace *mnt_userns, const struct path *path,
24762479
}
24772480

24782481
if (ceph_snap(inode) == CEPH_NOSNAP)
2479-
stat->dev = inode->i_sb->s_dev;
2482+
stat->dev = sb->s_dev;
24802483
else
24812484
stat->dev = ci->i_snapid_map ? ci->i_snapid_map->dev : 0;
24822485

24832486
if (S_ISDIR(inode->i_mode)) {
2484-
if (ceph_test_mount_opt(ceph_sb_to_client(inode->i_sb),
2485-
RBYTES))
2487+
if (ceph_test_mount_opt(ceph_sb_to_client(sb), RBYTES)) {
24862488
stat->size = ci->i_rbytes;
2487-
else
2489+
} else if (ceph_snap(inode) == CEPH_SNAPDIR) {
2490+
struct ceph_inode_info *pci;
2491+
struct ceph_snap_realm *realm;
2492+
struct inode *parent;
2493+
2494+
parent = ceph_lookup_inode(sb, ceph_ino(inode));
2495+
if (!parent)
2496+
return PTR_ERR(parent);
2497+
2498+
pci = ceph_inode(parent);
2499+
spin_lock(&pci->i_ceph_lock);
2500+
realm = pci->i_snap_realm;
2501+
if (realm)
2502+
stat->size = realm->num_snaps;
2503+
else
2504+
stat->size = 0;
2505+
spin_unlock(&pci->i_ceph_lock);
2506+
iput(parent);
2507+
} else {
24882508
stat->size = ci->i_files + ci->i_subdirs;
2509+
}
24892510
stat->blocks = 0;
24902511
stat->blksize = 65536;
24912512
/*

fs/ceph/mds_client.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2318,6 +2318,7 @@ ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode)
23182318
INIT_LIST_HEAD(&req->r_unsafe_dir_item);
23192319
INIT_LIST_HEAD(&req->r_unsafe_target_item);
23202320
req->r_fmode = -1;
2321+
req->r_feature_needed = -1;
23212322
kref_init(&req->r_kref);
23222323
RB_CLEAR_NODE(&req->r_node);
23232324
INIT_LIST_HEAD(&req->r_wait);
@@ -2916,6 +2917,16 @@ static void __do_request(struct ceph_mds_client *mdsc,
29162917

29172918
dout("do_request mds%d session %p state %s\n", mds, session,
29182919
ceph_session_state_name(session->s_state));
2920+
2921+
/*
2922+
* The old ceph will crash the MDSs when see unknown OPs
2923+
*/
2924+
if (req->r_feature_needed > 0 &&
2925+
!test_bit(req->r_feature_needed, &session->s_features)) {
2926+
err = -EOPNOTSUPP;
2927+
goto out_session;
2928+
}
2929+
29192930
if (session->s_state != CEPH_MDS_SESSION_OPEN &&
29202931
session->s_state != CEPH_MDS_SESSION_HUNG) {
29212932
/*

fs/ceph/mds_client.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ enum ceph_feature_type {
3131
CEPHFS_FEATURE_METRIC_COLLECT,
3232
CEPHFS_FEATURE_ALTERNATE_NAME,
3333
CEPHFS_FEATURE_NOTIFY_SESSION_STATE,
34+
CEPHFS_FEATURE_OP_GETVXATTR,
3435

35-
CEPHFS_FEATURE_MAX = CEPHFS_FEATURE_NOTIFY_SESSION_STATE,
36+
CEPHFS_FEATURE_MAX = CEPHFS_FEATURE_OP_GETVXATTR,
3637
};
3738

3839
#define CEPHFS_FEATURES_CLIENT_SUPPORTED { \
@@ -44,6 +45,7 @@ enum ceph_feature_type {
4445
CEPHFS_FEATURE_DELEG_INO, \
4546
CEPHFS_FEATURE_METRIC_COLLECT, \
4647
CEPHFS_FEATURE_NOTIFY_SESSION_STATE, \
48+
CEPHFS_FEATURE_OP_GETVXATTR, \
4749
}
4850

4951
/*
@@ -336,6 +338,8 @@ struct ceph_mds_request {
336338
long long r_dir_ordered_cnt;
337339
int r_readdir_cache_idx;
338340

341+
int r_feature_needed;
342+
339343
struct ceph_cap_reservation r_caps_reservation;
340344
};
341345

include/linux/ceph/messenger.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,6 @@ struct ceph_msg_data_cursor {
207207

208208
struct ceph_msg_data *data; /* current data item */
209209
size_t resid; /* bytes not yet consumed */
210-
bool last_piece; /* current is last piece */
211210
bool need_crc; /* crc update needed */
212211
union {
213212
#ifdef CONFIG_BLOCK
@@ -498,8 +497,7 @@ void ceph_con_discard_requeued(struct ceph_connection *con, u64 reconnect_seq);
498497
void ceph_msg_data_cursor_init(struct ceph_msg_data_cursor *cursor,
499498
struct ceph_msg *msg, size_t length);
500499
struct page *ceph_msg_data_next(struct ceph_msg_data_cursor *cursor,
501-
size_t *page_offset, size_t *length,
502-
bool *last_piece);
500+
size_t *page_offset, size_t *length);
503501
void ceph_msg_data_advance(struct ceph_msg_data_cursor *cursor, size_t bytes);
504502

505503
u32 ceph_crc32c_page(u32 crc, struct page *page, unsigned int page_offset,

net/ceph/messenger.c

Lines changed: 5 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,6 @@ static void ceph_msg_data_bio_cursor_init(struct ceph_msg_data_cursor *cursor,
728728
it->iter.bi_size = cursor->resid;
729729

730730
BUG_ON(cursor->resid < bio_iter_len(it->bio, it->iter));
731-
cursor->last_piece = cursor->resid == bio_iter_len(it->bio, it->iter);
732731
}
733732

734733
static struct page *ceph_msg_data_bio_next(struct ceph_msg_data_cursor *cursor,
@@ -754,10 +753,8 @@ static bool ceph_msg_data_bio_advance(struct ceph_msg_data_cursor *cursor,
754753
cursor->resid -= bytes;
755754
bio_advance_iter(it->bio, &it->iter, bytes);
756755

757-
if (!cursor->resid) {
758-
BUG_ON(!cursor->last_piece);
756+
if (!cursor->resid)
759757
return false; /* no more data */
760-
}
761758

762759
if (!bytes || (it->iter.bi_size && it->iter.bi_bvec_done &&
763760
page == bio_iter_page(it->bio, it->iter)))
@@ -770,9 +767,7 @@ static bool ceph_msg_data_bio_advance(struct ceph_msg_data_cursor *cursor,
770767
it->iter.bi_size = cursor->resid;
771768
}
772769

773-
BUG_ON(cursor->last_piece);
774770
BUG_ON(cursor->resid < bio_iter_len(it->bio, it->iter));
775-
cursor->last_piece = cursor->resid == bio_iter_len(it->bio, it->iter);
776771
return true;
777772
}
778773
#endif /* CONFIG_BLOCK */
@@ -788,8 +783,6 @@ static void ceph_msg_data_bvecs_cursor_init(struct ceph_msg_data_cursor *cursor,
788783
cursor->bvec_iter.bi_size = cursor->resid;
789784

790785
BUG_ON(cursor->resid < bvec_iter_len(bvecs, cursor->bvec_iter));
791-
cursor->last_piece =
792-
cursor->resid == bvec_iter_len(bvecs, cursor->bvec_iter);
793786
}
794787

795788
static struct page *ceph_msg_data_bvecs_next(struct ceph_msg_data_cursor *cursor,
@@ -815,19 +808,14 @@ static bool ceph_msg_data_bvecs_advance(struct ceph_msg_data_cursor *cursor,
815808
cursor->resid -= bytes;
816809
bvec_iter_advance(bvecs, &cursor->bvec_iter, bytes);
817810

818-
if (!cursor->resid) {
819-
BUG_ON(!cursor->last_piece);
811+
if (!cursor->resid)
820812
return false; /* no more data */
821-
}
822813

823814
if (!bytes || (cursor->bvec_iter.bi_bvec_done &&
824815
page == bvec_iter_page(bvecs, cursor->bvec_iter)))
825816
return false; /* more bytes to process in this segment */
826817

827-
BUG_ON(cursor->last_piece);
828818
BUG_ON(cursor->resid < bvec_iter_len(bvecs, cursor->bvec_iter));
829-
cursor->last_piece =
830-
cursor->resid == bvec_iter_len(bvecs, cursor->bvec_iter);
831819
return true;
832820
}
833821

@@ -853,7 +841,6 @@ static void ceph_msg_data_pages_cursor_init(struct ceph_msg_data_cursor *cursor,
853841
BUG_ON(page_count > (int)USHRT_MAX);
854842
cursor->page_count = (unsigned short)page_count;
855843
BUG_ON(length > SIZE_MAX - cursor->page_offset);
856-
cursor->last_piece = cursor->page_offset + cursor->resid <= PAGE_SIZE;
857844
}
858845

859846
static struct page *
@@ -868,11 +855,7 @@ ceph_msg_data_pages_next(struct ceph_msg_data_cursor *cursor,
868855
BUG_ON(cursor->page_offset >= PAGE_SIZE);
869856

870857
*page_offset = cursor->page_offset;
871-
if (cursor->last_piece)
872-
*length = cursor->resid;
873-
else
874-
*length = PAGE_SIZE - *page_offset;
875-
858+
*length = min_t(size_t, cursor->resid, PAGE_SIZE - *page_offset);
876859
return data->pages[cursor->page_index];
877860
}
878861

@@ -897,8 +880,6 @@ static bool ceph_msg_data_pages_advance(struct ceph_msg_data_cursor *cursor,
897880

898881
BUG_ON(cursor->page_index >= cursor->page_count);
899882
cursor->page_index++;
900-
cursor->last_piece = cursor->resid <= PAGE_SIZE;
901-
902883
return true;
903884
}
904885

@@ -928,7 +909,6 @@ ceph_msg_data_pagelist_cursor_init(struct ceph_msg_data_cursor *cursor,
928909
cursor->resid = min(length, pagelist->length);
929910
cursor->page = page;
930911
cursor->offset = 0;
931-
cursor->last_piece = cursor->resid <= PAGE_SIZE;
932912
}
933913

934914
static struct page *
@@ -948,11 +928,7 @@ ceph_msg_data_pagelist_next(struct ceph_msg_data_cursor *cursor,
948928

949929
/* offset of first page in pagelist is always 0 */
950930
*page_offset = cursor->offset & ~PAGE_MASK;
951-
if (cursor->last_piece)
952-
*length = cursor->resid;
953-
else
954-
*length = PAGE_SIZE - *page_offset;
955-
931+
*length = min_t(size_t, cursor->resid, PAGE_SIZE - *page_offset);
956932
return cursor->page;
957933
}
958934

@@ -985,8 +961,6 @@ static bool ceph_msg_data_pagelist_advance(struct ceph_msg_data_cursor *cursor,
985961

986962
BUG_ON(list_is_last(&cursor->page->lru, &pagelist->head));
987963
cursor->page = list_next_entry(cursor->page, lru);
988-
cursor->last_piece = cursor->resid <= PAGE_SIZE;
989-
990964
return true;
991965
}
992966

@@ -1044,8 +1018,7 @@ void ceph_msg_data_cursor_init(struct ceph_msg_data_cursor *cursor,
10441018
* Indicate whether this is the last piece in this data item.
10451019
*/
10461020
struct page *ceph_msg_data_next(struct ceph_msg_data_cursor *cursor,
1047-
size_t *page_offset, size_t *length,
1048-
bool *last_piece)
1021+
size_t *page_offset, size_t *length)
10491022
{
10501023
struct page *page;
10511024

@@ -1074,8 +1047,6 @@ struct page *ceph_msg_data_next(struct ceph_msg_data_cursor *cursor,
10741047
BUG_ON(*page_offset + *length > PAGE_SIZE);
10751048
BUG_ON(!*length);
10761049
BUG_ON(*length > cursor->resid);
1077-
if (last_piece)
1078-
*last_piece = cursor->last_piece;
10791050

10801051
return page;
10811052
}
@@ -1112,7 +1083,6 @@ void ceph_msg_data_advance(struct ceph_msg_data_cursor *cursor, size_t bytes)
11121083
cursor->total_resid -= bytes;
11131084

11141085
if (!cursor->resid && cursor->total_resid) {
1115-
WARN_ON(!cursor->last_piece);
11161086
cursor->data++;
11171087
__ceph_msg_data_cursor_init(cursor);
11181088
new_piece = true;

net/ceph/messenger_v1.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ static int write_partial_message_data(struct ceph_connection *con)
495495
continue;
496496
}
497497

498-
page = ceph_msg_data_next(cursor, &page_offset, &length, NULL);
498+
page = ceph_msg_data_next(cursor, &page_offset, &length);
499499
if (length == cursor->total_resid)
500500
more = MSG_MORE;
501501
ret = ceph_tcp_sendpage(con->sock, page, page_offset, length,
@@ -1008,7 +1008,7 @@ static int read_partial_msg_data(struct ceph_connection *con)
10081008
continue;
10091009
}
10101010

1011-
page = ceph_msg_data_next(cursor, &page_offset, &length, NULL);
1011+
page = ceph_msg_data_next(cursor, &page_offset, &length);
10121012
ret = ceph_tcp_recvpage(con->sock, page, page_offset, length);
10131013
if (ret <= 0) {
10141014
if (do_datacrc)
@@ -1050,7 +1050,7 @@ static int read_partial_msg_data_bounce(struct ceph_connection *con)
10501050
continue;
10511051
}
10521052

1053-
page = ceph_msg_data_next(cursor, &off, &len, NULL);
1053+
page = ceph_msg_data_next(cursor, &off, &len);
10541054
ret = ceph_tcp_recvpage(con->sock, con->bounce_page, 0, len);
10551055
if (ret <= 0) {
10561056
con->in_data_crc = crc;

net/ceph/messenger_v2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -862,7 +862,7 @@ static void get_bvec_at(struct ceph_msg_data_cursor *cursor,
862862
ceph_msg_data_advance(cursor, 0);
863863

864864
/* get a piece of data, cursor isn't advanced */
865-
page = ceph_msg_data_next(cursor, &off, &len, NULL);
865+
page = ceph_msg_data_next(cursor, &off, &len);
866866

867867
bv->bv_page = page;
868868
bv->bv_offset = off;

0 commit comments

Comments
 (0)