Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/sage/ceph-client

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client:
  ceph: fix get_ticket_handler() error handling
  ceph: don't BUG on ENOMEM during mds reconnect
  ceph: ceph_mdsc_build_path() returns an ERR_PTR
  ceph: Fix warnings
  ceph: ceph_get_inode() returns an ERR_PTR
  ceph: initialize fields on new dentry_infos
  ceph: maintain i_head_snapc when any caps are dirty, not just for data
  ceph: fix osd request lru adjustment when sending request
  ceph: don't improperly set dir complete when holding EXCL cap
  mm: exporting account_page_dirty
  ceph: direct requests in snapped namespace based on nonsnap parent
  ceph: queue cap snap writeback for realm children on snap update
  ceph: include dirty xattrs state in snapped caps
  ceph: fix xattr cap writeback
  ceph: fix multiple mds session shutdown
  • Loading branch information
torvalds committed Aug 28, 2010
2 parents 6f4dbec + b545787 commit 997396a
Show file tree
Hide file tree
Showing 14 changed files with 185 additions and 107 deletions.
12 changes: 3 additions & 9 deletions fs/ceph/addr.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ static int ceph_set_page_dirty(struct page *page)

/* dirty the head */
spin_lock(&inode->i_lock);
if (ci->i_wrbuffer_ref_head == 0)
if (ci->i_head_snapc == NULL)
ci->i_head_snapc = ceph_get_snap_context(snapc);
++ci->i_wrbuffer_ref_head;
if (ci->i_wrbuffer_ref == 0)
Expand All @@ -105,13 +105,7 @@ static int ceph_set_page_dirty(struct page *page)
spin_lock_irq(&mapping->tree_lock);
if (page->mapping) { /* Race with truncate? */
WARN_ON_ONCE(!PageUptodate(page));

if (mapping_cap_account_dirty(mapping)) {
__inc_zone_page_state(page, NR_FILE_DIRTY);
__inc_bdi_stat(mapping->backing_dev_info,
BDI_RECLAIMABLE);
task_io_account_write(PAGE_CACHE_SIZE);
}
account_page_dirtied(page, page->mapping);
radix_tree_tag_set(&mapping->page_tree,
page_index(page), PAGECACHE_TAG_DIRTY);

Expand Down Expand Up @@ -352,7 +346,7 @@ static struct ceph_snap_context *get_oldest_context(struct inode *inode,
break;
}
}
if (!snapc && ci->i_head_snapc) {
if (!snapc && ci->i_wrbuffer_ref_head) {
snapc = ceph_get_snap_context(ci->i_head_snapc);
dout(" head snapc %p has %d dirty pages\n",
snapc, ci->i_wrbuffer_ref_head);
Expand Down
15 changes: 9 additions & 6 deletions fs/ceph/auth_x.c
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed)

th = get_ticket_handler(ac, service);

if (!th) {
if (IS_ERR(th)) {
*pneed |= service;
continue;
}
Expand All @@ -399,6 +399,9 @@ static int ceph_x_build_request(struct ceph_auth_client *ac,
struct ceph_x_ticket_handler *th =
get_ticket_handler(ac, CEPH_ENTITY_TYPE_AUTH);

if (IS_ERR(th))
return PTR_ERR(th);

ceph_x_validate_tickets(ac, &need);

dout("build_request want %x have %x need %x\n",
Expand Down Expand Up @@ -450,7 +453,6 @@ static int ceph_x_build_request(struct ceph_auth_client *ac,
return -ERANGE;
head->op = cpu_to_le16(CEPHX_GET_PRINCIPAL_SESSION_KEY);

BUG_ON(!th);
ret = ceph_x_build_authorizer(ac, th, &xi->auth_authorizer);
if (ret)
return ret;
Expand Down Expand Up @@ -505,7 +507,8 @@ static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result,

case CEPHX_GET_PRINCIPAL_SESSION_KEY:
th = get_ticket_handler(ac, CEPH_ENTITY_TYPE_AUTH);
BUG_ON(!th);
if (IS_ERR(th))
return PTR_ERR(th);
ret = ceph_x_proc_ticket_reply(ac, &th->session_key,
buf + sizeof(*head), end);
break;
Expand Down Expand Up @@ -563,8 +566,8 @@ static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac,
void *end = p + sizeof(au->reply_buf);

th = get_ticket_handler(ac, au->service);
if (!th)
return -EIO; /* hrm! */
if (IS_ERR(th))
return PTR_ERR(th);
ret = ceph_x_decrypt(&th->session_key, &p, end, &reply, sizeof(reply));
if (ret < 0)
return ret;
Expand Down Expand Up @@ -626,7 +629,7 @@ static void ceph_x_invalidate_authorizer(struct ceph_auth_client *ac,
struct ceph_x_ticket_handler *th;

th = get_ticket_handler(ac, peer_type);
if (th && !IS_ERR(th))
if (!IS_ERR(th))
remove_ticket_handler(ac, th);
}

Expand Down
32 changes: 23 additions & 9 deletions fs/ceph/caps.c
Original file line number Diff line number Diff line change
Expand Up @@ -1082,6 +1082,7 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,
gid_t gid;
struct ceph_mds_session *session;
u64 xattr_version = 0;
struct ceph_buffer *xattr_blob = NULL;
int delayed = 0;
u64 flush_tid = 0;
int i;
Expand Down Expand Up @@ -1142,6 +1143,10 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,
for (i = 0; i < CEPH_CAP_BITS; i++)
if (flushing & (1 << i))
ci->i_cap_flush_tid[i] = flush_tid;

follows = ci->i_head_snapc->seq;
} else {
follows = 0;
}

keep = cap->implemented;
Expand All @@ -1155,24 +1160,22 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,
mtime = inode->i_mtime;
atime = inode->i_atime;
time_warp_seq = ci->i_time_warp_seq;
follows = ci->i_snap_realm->cached_context->seq;
uid = inode->i_uid;
gid = inode->i_gid;
mode = inode->i_mode;

if (dropping & CEPH_CAP_XATTR_EXCL) {
if (flushing & CEPH_CAP_XATTR_EXCL) {
__ceph_build_xattrs_blob(ci);
xattr_version = ci->i_xattrs.version + 1;
xattr_blob = ci->i_xattrs.blob;
xattr_version = ci->i_xattrs.version;
}

spin_unlock(&inode->i_lock);

ret = send_cap_msg(session, ceph_vino(inode).ino, cap_id,
op, keep, want, flushing, seq, flush_tid, issue_seq, mseq,
size, max_size, &mtime, &atime, time_warp_seq,
uid, gid, mode,
xattr_version,
(flushing & CEPH_CAP_XATTR_EXCL) ? ci->i_xattrs.blob : NULL,
uid, gid, mode, xattr_version, xattr_blob,
follows);
if (ret < 0) {
dout("error sending cap msg, must requeue %p\n", inode);
Expand Down Expand Up @@ -1282,7 +1285,7 @@ void __ceph_flush_snaps(struct ceph_inode_info *ci,
&capsnap->mtime, &capsnap->atime,
capsnap->time_warp_seq,
capsnap->uid, capsnap->gid, capsnap->mode,
0, NULL,
capsnap->xattr_version, capsnap->xattr_blob,
capsnap->follows);

next_follows = capsnap->follows + 1;
Expand Down Expand Up @@ -1332,7 +1335,11 @@ void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask)
ceph_cap_string(was | mask));
ci->i_dirty_caps |= mask;
if (was == 0) {
dout(" inode %p now dirty\n", &ci->vfs_inode);
if (!ci->i_head_snapc)
ci->i_head_snapc = ceph_get_snap_context(
ci->i_snap_realm->cached_context);
dout(" inode %p now dirty snapc %p\n", &ci->vfs_inode,
ci->i_head_snapc);
BUG_ON(!list_empty(&ci->i_dirty_item));
spin_lock(&mdsc->cap_dirty_lock);
list_add(&ci->i_dirty_item, &mdsc->cap_dirty);
Expand Down Expand Up @@ -2190,7 +2197,9 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,

if (ci->i_head_snapc == snapc) {
ci->i_wrbuffer_ref_head -= nr;
if (!ci->i_wrbuffer_ref_head) {
if (ci->i_wrbuffer_ref_head == 0 &&
ci->i_dirty_caps == 0 && ci->i_flushing_caps == 0) {
BUG_ON(!ci->i_head_snapc);
ceph_put_snap_context(ci->i_head_snapc);
ci->i_head_snapc = NULL;
}
Expand Down Expand Up @@ -2483,6 +2492,11 @@ static void handle_cap_flush_ack(struct inode *inode, u64 flush_tid,
dout(" inode %p now clean\n", inode);
BUG_ON(!list_empty(&ci->i_dirty_item));
drop = 1;
if (ci->i_wrbuffer_ref_head == 0) {
BUG_ON(!ci->i_head_snapc);
ceph_put_snap_context(ci->i_head_snapc);
ci->i_head_snapc = NULL;
}
} else {
BUG_ON(list_empty(&ci->i_dirty_item));
}
Expand Down
4 changes: 4 additions & 0 deletions fs/ceph/debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ static int mdsc_show(struct seq_file *s, void *p)
} else if (req->r_dentry) {
path = ceph_mdsc_build_path(req->r_dentry, &pathlen,
&pathbase, 0);
if (IS_ERR(path))
path = NULL;
spin_lock(&req->r_dentry->d_lock);
seq_printf(s, " #%llx/%.*s (%s)",
ceph_ino(req->r_dentry->d_parent->d_inode),
Expand All @@ -187,6 +189,8 @@ static int mdsc_show(struct seq_file *s, void *p)
if (req->r_old_dentry) {
path = ceph_mdsc_build_path(req->r_old_dentry, &pathlen,
&pathbase, 0);
if (IS_ERR(path))
path = NULL;
spin_lock(&req->r_old_dentry->d_lock);
seq_printf(s, " #%llx/%.*s (%s)",
ceph_ino(req->r_old_dentry->d_parent->d_inode),
Expand Down
2 changes: 1 addition & 1 deletion fs/ceph/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ int ceph_init_dentry(struct dentry *dentry)
else
dentry->d_op = &ceph_snap_dentry_ops;

di = kmem_cache_alloc(ceph_dentry_cachep, GFP_NOFS);
di = kmem_cache_alloc(ceph_dentry_cachep, GFP_NOFS | __GFP_ZERO);
if (!di)
return -ENOMEM; /* oh well */

Expand Down
5 changes: 3 additions & 2 deletions fs/ceph/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,7 @@ static int fill_inode(struct inode *inode,
if (ci->i_files == 0 && ci->i_subdirs == 0 &&
ceph_snap(inode) == CEPH_NOSNAP &&
(le32_to_cpu(info->cap.caps) & CEPH_CAP_FILE_SHARED) &&
(issued & CEPH_CAP_FILE_EXCL) == 0 &&
(ci->i_ceph_flags & CEPH_I_COMPLETE) == 0) {
dout(" marking %p complete (empty)\n", inode);
ci->i_ceph_flags |= CEPH_I_COMPLETE;
Expand Down Expand Up @@ -1229,11 +1230,11 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req,
in = dn->d_inode;
} else {
in = ceph_get_inode(parent->d_sb, vino);
if (in == NULL) {
if (IS_ERR(in)) {
dout("new_inode badness\n");
d_delete(dn);
dput(dn);
err = -ENOMEM;
err = PTR_ERR(in);
goto out;
}
dn = splice_dentry(dn, in, NULL);
Expand Down
14 changes: 9 additions & 5 deletions fs/ceph/locks.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
length = fl->fl_end - fl->fl_start + 1;

err = ceph_lock_message(CEPH_LOCK_FCNTL, op, file,
(u64)fl->fl_pid, (u64)fl->fl_nspid,
(u64)fl->fl_pid,
(u64)(unsigned long)fl->fl_nspid,
lock_cmd, fl->fl_start,
length, wait);
if (!err) {
Expand All @@ -92,7 +93,8 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
/* undo! This should only happen if the kernel detects
* local deadlock. */
ceph_lock_message(CEPH_LOCK_FCNTL, op, file,
(u64)fl->fl_pid, (u64)fl->fl_nspid,
(u64)fl->fl_pid,
(u64)(unsigned long)fl->fl_nspid,
CEPH_LOCK_UNLOCK, fl->fl_start,
length, 0);
dout("got %d on posix_lock_file, undid lock", err);
Expand Down Expand Up @@ -132,7 +134,8 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl)
length = fl->fl_end - fl->fl_start + 1;

err = ceph_lock_message(CEPH_LOCK_FLOCK, CEPH_MDS_OP_SETFILELOCK,
file, (u64)fl->fl_pid, (u64)fl->fl_nspid,
file, (u64)fl->fl_pid,
(u64)(unsigned long)fl->fl_nspid,
lock_cmd, fl->fl_start,
length, wait);
if (!err) {
Expand All @@ -141,7 +144,7 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl)
ceph_lock_message(CEPH_LOCK_FLOCK,
CEPH_MDS_OP_SETFILELOCK,
file, (u64)fl->fl_pid,
(u64)fl->fl_nspid,
(u64)(unsigned long)fl->fl_nspid,
CEPH_LOCK_UNLOCK, fl->fl_start,
length, 0);
dout("got %d on flock_lock_file_wait, undid lock", err);
Expand Down Expand Up @@ -235,7 +238,8 @@ int lock_to_ceph_filelock(struct file_lock *lock,
cephlock->length = cpu_to_le64(lock->fl_end - lock->fl_start + 1);
cephlock->client = cpu_to_le64(0);
cephlock->pid = cpu_to_le64(lock->fl_pid);
cephlock->pid_namespace = cpu_to_le64((u64)lock->fl_nspid);
cephlock->pid_namespace =
cpu_to_le64((u64)(unsigned long)lock->fl_nspid);

switch (lock->fl_type) {
case F_RDLCK:
Expand Down
Loading

0 comments on commit 997396a

Please sign in to comment.