Skip to content

Commit ffdb8f1

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client: ceph: unwind canceled flock state ceph: fix ENOENT logic in striped_read ceph: fix short sync reads from the OSD ceph: fix sync vs canceled write ceph: use ihold when we already have an inode ref
2 parents 80dadf8 + 0c1f91f commit ffdb8f1

File tree

11 files changed

+80
-58
lines changed

11 files changed

+80
-58
lines changed

fs/ceph/addr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ static int ceph_writepage(struct page *page, struct writeback_control *wbc)
453453
int err;
454454
struct inode *inode = page->mapping->host;
455455
BUG_ON(!inode);
456-
igrab(inode);
456+
ihold(inode);
457457
err = writepage_nounlock(page, wbc);
458458
unlock_page(page);
459459
iput(inode);

fs/ceph/caps.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2940,14 +2940,12 @@ void ceph_flush_dirty_caps(struct ceph_mds_client *mdsc)
29402940
while (!list_empty(&mdsc->cap_dirty)) {
29412941
ci = list_first_entry(&mdsc->cap_dirty, struct ceph_inode_info,
29422942
i_dirty_item);
2943-
inode = igrab(&ci->vfs_inode);
2943+
inode = &ci->vfs_inode;
2944+
ihold(inode);
29442945
dout("flush_dirty_caps %p\n", inode);
29452946
spin_unlock(&mdsc->cap_dirty_lock);
2946-
if (inode) {
2947-
ceph_check_caps(ci, CHECK_CAPS_NODELAY|CHECK_CAPS_FLUSH,
2948-
NULL);
2949-
iput(inode);
2950-
}
2947+
ceph_check_caps(ci, CHECK_CAPS_NODELAY|CHECK_CAPS_FLUSH, NULL);
2948+
iput(inode);
29512949
spin_lock(&mdsc->cap_dirty_lock);
29522950
}
29532951
spin_unlock(&mdsc->cap_dirty_lock);

fs/ceph/dir.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,8 @@ static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir)
308308
req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS);
309309
if (IS_ERR(req))
310310
return PTR_ERR(req);
311-
req->r_inode = igrab(inode);
311+
req->r_inode = inode;
312+
ihold(inode);
312313
req->r_dentry = dget(filp->f_dentry);
313314
/* hints to request -> mds selection code */
314315
req->r_direct_mode = USE_AUTH_MDS;
@@ -787,10 +788,12 @@ static int ceph_link(struct dentry *old_dentry, struct inode *dir,
787788
req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
788789
req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
789790
err = ceph_mdsc_do_request(mdsc, dir, req);
790-
if (err)
791+
if (err) {
791792
d_drop(dentry);
792-
else if (!req->r_reply_info.head->is_dentry)
793-
d_instantiate(dentry, igrab(old_dentry->d_inode));
793+
} else if (!req->r_reply_info.head->is_dentry) {
794+
ihold(old_dentry->d_inode);
795+
d_instantiate(dentry, old_dentry->d_inode);
796+
}
794797
ceph_mdsc_put_request(req);
795798
return err;
796799
}

fs/ceph/export.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ static struct dentry *__fh_to_dentry(struct super_block *sb,
109109
err = ceph_mdsc_do_request(mdsc, NULL, req);
110110
inode = req->r_target_inode;
111111
if (inode)
112-
igrab(inode);
112+
ihold(inode);
113113
ceph_mdsc_put_request(req);
114114
if (!inode)
115115
return ERR_PTR(-ESTALE);
@@ -167,7 +167,7 @@ static struct dentry *__cfh_to_dentry(struct super_block *sb,
167167
err = ceph_mdsc_do_request(mdsc, NULL, req);
168168
inode = req->r_target_inode;
169169
if (inode)
170-
igrab(inode);
170+
ihold(inode);
171171
ceph_mdsc_put_request(req);
172172
if (!inode)
173173
return ERR_PTR(err ? err : -ESTALE);

fs/ceph/file.c

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,8 @@ int ceph_open(struct inode *inode, struct file *file)
191191
err = PTR_ERR(req);
192192
goto out;
193193
}
194-
req->r_inode = igrab(inode);
194+
req->r_inode = inode;
195+
ihold(inode);
195196
req->r_num_caps = 1;
196197
err = ceph_mdsc_do_request(mdsc, parent_inode, req);
197198
if (!err)
@@ -282,7 +283,7 @@ int ceph_release(struct inode *inode, struct file *file)
282283
static int striped_read(struct inode *inode,
283284
u64 off, u64 len,
284285
struct page **pages, int num_pages,
285-
int *checkeof, bool align_to_pages,
286+
int *checkeof, bool o_direct,
286287
unsigned long buf_align)
287288
{
288289
struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
@@ -307,7 +308,7 @@ static int striped_read(struct inode *inode,
307308
io_align = off & ~PAGE_MASK;
308309

309310
more:
310-
if (align_to_pages)
311+
if (o_direct)
311312
page_align = (pos - io_align + buf_align) & ~PAGE_MASK;
312313
else
313314
page_align = pos & ~PAGE_MASK;
@@ -317,10 +318,10 @@ static int striped_read(struct inode *inode,
317318
ci->i_truncate_seq,
318319
ci->i_truncate_size,
319320
page_pos, pages_left, page_align);
320-
hit_stripe = this_len < left;
321-
was_short = ret >= 0 && ret < this_len;
322321
if (ret == -ENOENT)
323322
ret = 0;
323+
hit_stripe = this_len < left;
324+
was_short = ret >= 0 && ret < this_len;
324325
dout("striped_read %llu~%u (read %u) got %d%s%s\n", pos, left, read,
325326
ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : "");
326327

@@ -345,20 +346,22 @@ static int striped_read(struct inode *inode,
345346
}
346347

347348
if (was_short) {
348-
/* was original extent fully inside i_size? */
349-
if (pos + left <= inode->i_size) {
350-
dout("zero tail\n");
351-
ceph_zero_page_vector_range(page_off + read, len - read,
349+
/* did we bounce off eof? */
350+
if (pos + left > inode->i_size)
351+
*checkeof = 1;
352+
353+
/* zero trailing bytes (inside i_size) */
354+
if (left > 0 && pos < inode->i_size) {
355+
if (pos + left > inode->i_size)
356+
left = inode->i_size - pos;
357+
358+
dout("zero tail %d\n", left);
359+
ceph_zero_page_vector_range(page_off + read, left,
352360
pages);
353-
read = len;
354-
goto out;
361+
read += left;
355362
}
356-
357-
/* check i_size */
358-
*checkeof = 1;
359363
}
360364

361-
out:
362365
if (ret >= 0)
363366
ret = read;
364367
dout("striped_read returns %d\n", ret);
@@ -658,7 +661,7 @@ static ssize_t ceph_aio_read(struct kiocb *iocb, const struct iovec *iov,
658661

659662
/* hit EOF or hole? */
660663
if (statret == 0 && *ppos < inode->i_size) {
661-
dout("aio_read sync_read hit hole, reading more\n");
664+
dout("aio_read sync_read hit hole, ppos %lld < size %lld, reading more\n", *ppos, inode->i_size);
662665
read += ret;
663666
base += ret;
664667
len -= ret;

fs/ceph/inode.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,10 +1101,10 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
11011101
goto done;
11021102
}
11031103
req->r_dentry = dn; /* may have spliced */
1104-
igrab(in);
1104+
ihold(in);
11051105
} else if (ceph_ino(in) == vino.ino &&
11061106
ceph_snap(in) == vino.snap) {
1107-
igrab(in);
1107+
ihold(in);
11081108
} else {
11091109
dout(" %p links to %p %llx.%llx, not %llx.%llx\n",
11101110
dn, in, ceph_ino(in), ceph_snap(in),
@@ -1144,7 +1144,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
11441144
goto done;
11451145
}
11461146
req->r_dentry = dn; /* may have spliced */
1147-
igrab(in);
1147+
ihold(in);
11481148
rinfo->head->is_dentry = 1; /* fool notrace handlers */
11491149
}
11501150

@@ -1328,7 +1328,7 @@ void ceph_queue_writeback(struct inode *inode)
13281328
if (queue_work(ceph_inode_to_client(inode)->wb_wq,
13291329
&ceph_inode(inode)->i_wb_work)) {
13301330
dout("ceph_queue_writeback %p\n", inode);
1331-
igrab(inode);
1331+
ihold(inode);
13321332
} else {
13331333
dout("ceph_queue_writeback %p failed\n", inode);
13341334
}
@@ -1353,7 +1353,7 @@ void ceph_queue_invalidate(struct inode *inode)
13531353
if (queue_work(ceph_inode_to_client(inode)->pg_inv_wq,
13541354
&ceph_inode(inode)->i_pg_inv_work)) {
13551355
dout("ceph_queue_invalidate %p\n", inode);
1356-
igrab(inode);
1356+
ihold(inode);
13571357
} else {
13581358
dout("ceph_queue_invalidate %p failed\n", inode);
13591359
}
@@ -1477,7 +1477,7 @@ void ceph_queue_vmtruncate(struct inode *inode)
14771477
if (queue_work(ceph_sb_to_client(inode->i_sb)->trunc_wq,
14781478
&ci->i_vmtruncate_work)) {
14791479
dout("ceph_queue_vmtruncate %p\n", inode);
1480-
igrab(inode);
1480+
ihold(inode);
14811481
} else {
14821482
dout("ceph_queue_vmtruncate %p failed, pending=%d\n",
14831483
inode, ci->i_truncate_pending);
@@ -1738,7 +1738,8 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
17381738
__mark_inode_dirty(inode, inode_dirty_flags);
17391739

17401740
if (mask) {
1741-
req->r_inode = igrab(inode);
1741+
req->r_inode = inode;
1742+
ihold(inode);
17421743
req->r_inode_drop = release;
17431744
req->r_args.setattr.mask = cpu_to_le32(mask);
17441745
req->r_num_caps = 1;
@@ -1779,7 +1780,8 @@ int ceph_do_getattr(struct inode *inode, int mask)
17791780
req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_GETATTR, USE_ANY_MDS);
17801781
if (IS_ERR(req))
17811782
return PTR_ERR(req);
1782-
req->r_inode = igrab(inode);
1783+
req->r_inode = inode;
1784+
ihold(inode);
17831785
req->r_num_caps = 1;
17841786
req->r_args.getattr.mask = cpu_to_le32(mask);
17851787
err = ceph_mdsc_do_request(mdsc, NULL, req);

fs/ceph/ioctl.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ static long ceph_ioctl_set_layout(struct file *file, void __user *arg)
7373
USE_AUTH_MDS);
7474
if (IS_ERR(req))
7575
return PTR_ERR(req);
76-
req->r_inode = igrab(inode);
76+
req->r_inode = inode;
77+
ihold(inode);
7778
req->r_inode_drop = CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_EXCL;
7879

7980
req->r_args.setlayout.layout.fl_stripe_unit =
@@ -135,7 +136,8 @@ static long ceph_ioctl_set_layout_policy (struct file *file, void __user *arg)
135136

136137
if (IS_ERR(req))
137138
return PTR_ERR(req);
138-
req->r_inode = igrab(inode);
139+
req->r_inode = inode;
140+
ihold(inode);
139141

140142
req->r_args.setlayout.layout.fl_stripe_unit =
141143
cpu_to_le32(l.stripe_unit);

fs/ceph/locks.c

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file,
2323
req = ceph_mdsc_create_request(mdsc, operation, USE_AUTH_MDS);
2424
if (IS_ERR(req))
2525
return PTR_ERR(req);
26-
req->r_inode = igrab(inode);
26+
req->r_inode = inode;
27+
ihold(inode);
2728

2829
/* mds requires start and length rather than start and end */
2930
if (LLONG_MAX == fl->fl_end)
@@ -32,11 +33,10 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file,
3233
length = fl->fl_end - fl->fl_start + 1;
3334

3435
dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, "
35-
"length: %llu, wait: %d, type`: %d", (int)lock_type,
36+
"length: %llu, wait: %d, type: %d", (int)lock_type,
3637
(int)operation, (u64)fl->fl_pid, fl->fl_start,
3738
length, wait, fl->fl_type);
3839

39-
4040
req->r_args.filelock_change.rule = lock_type;
4141
req->r_args.filelock_change.type = cmd;
4242
req->r_args.filelock_change.pid = cpu_to_le64((u64)fl->fl_pid);
@@ -70,7 +70,7 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file,
7070
}
7171
ceph_mdsc_put_request(req);
7272
dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, "
73-
"length: %llu, wait: %d, type`: %d, err code %d", (int)lock_type,
73+
"length: %llu, wait: %d, type: %d, err code %d", (int)lock_type,
7474
(int)operation, (u64)fl->fl_pid, fl->fl_start,
7575
length, wait, fl->fl_type, err);
7676
return err;
@@ -109,16 +109,20 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
109109
dout("mds locked, locking locally");
110110
err = posix_lock_file(file, fl, NULL);
111111
if (err && (CEPH_MDS_OP_SETFILELOCK == op)) {
112-
/* undo! This should only happen if the kernel detects
113-
* local deadlock. */
112+
/* undo! This should only happen if
113+
* the kernel detects local
114+
* deadlock. */
114115
ceph_lock_message(CEPH_LOCK_FCNTL, op, file,
115116
CEPH_LOCK_UNLOCK, 0, fl);
116-
dout("got %d on posix_lock_file, undid lock", err);
117+
dout("got %d on posix_lock_file, undid lock",
118+
err);
117119
}
118120
}
119121

120-
} else {
121-
dout("mds returned error code %d", err);
122+
} else if (err == -ERESTARTSYS) {
123+
dout("undoing lock\n");
124+
ceph_lock_message(CEPH_LOCK_FCNTL, op, file,
125+
CEPH_LOCK_UNLOCK, 0, fl);
122126
}
123127
return err;
124128
}
@@ -155,8 +159,11 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl)
155159
file, CEPH_LOCK_UNLOCK, 0, fl);
156160
dout("got %d on flock_lock_file_wait, undid lock", err);
157161
}
158-
} else {
159-
dout("mds error code %d", err);
162+
} else if (err == -ERESTARTSYS) {
163+
dout("undoing lock\n");
164+
ceph_lock_message(CEPH_LOCK_FLOCK,
165+
CEPH_MDS_OP_SETFILELOCK,
166+
file, CEPH_LOCK_UNLOCK, 0, fl);
160167
}
161168
return err;
162169
}

fs/ceph/snap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,7 @@ static void flush_snaps(struct ceph_mds_client *mdsc)
722722
ci = list_first_entry(&mdsc->snap_flush_list,
723723
struct ceph_inode_info, i_snap_flush_item);
724724
inode = &ci->vfs_inode;
725-
igrab(inode);
725+
ihold(inode);
726726
spin_unlock(&mdsc->snap_flush_lock);
727727
spin_lock(&inode->i_lock);
728728
__ceph_flush_snaps(ci, &session, 0);

fs/ceph/xattr.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,8 @@ static int ceph_sync_setxattr(struct dentry *dentry, const char *name,
665665
err = PTR_ERR(req);
666666
goto out;
667667
}
668-
req->r_inode = igrab(inode);
668+
req->r_inode = inode;
669+
ihold(inode);
669670
req->r_inode_drop = CEPH_CAP_XATTR_SHARED;
670671
req->r_num_caps = 1;
671672
req->r_args.setxattr.flags = cpu_to_le32(flags);
@@ -795,7 +796,8 @@ static int ceph_send_removexattr(struct dentry *dentry, const char *name)
795796
USE_AUTH_MDS);
796797
if (IS_ERR(req))
797798
return PTR_ERR(req);
798-
req->r_inode = igrab(inode);
799+
req->r_inode = inode;
800+
ihold(inode);
799801
req->r_inode_drop = CEPH_CAP_XATTR_SHARED;
800802
req->r_num_caps = 1;
801803
req->r_path2 = kstrdup(name, GFP_NOFS);

net/ceph/osd_client.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,6 +1144,13 @@ static void handle_osds_timeout(struct work_struct *work)
11441144
round_jiffies_relative(delay));
11451145
}
11461146

1147+
static void complete_request(struct ceph_osd_request *req)
1148+
{
1149+
if (req->r_safe_callback)
1150+
req->r_safe_callback(req, NULL);
1151+
complete_all(&req->r_safe_completion); /* fsync waiter */
1152+
}
1153+
11471154
/*
11481155
* handle osd op reply. either call the callback if it is specified,
11491156
* or do the completion to wake up the waiting thread.
@@ -1226,11 +1233,8 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg,
12261233
else
12271234
complete_all(&req->r_completion);
12281235

1229-
if (flags & CEPH_OSD_FLAG_ONDISK) {
1230-
if (req->r_safe_callback)
1231-
req->r_safe_callback(req, msg);
1232-
complete_all(&req->r_safe_completion); /* fsync waiter */
1233-
}
1236+
if (flags & CEPH_OSD_FLAG_ONDISK)
1237+
complete_request(req);
12341238

12351239
done:
12361240
dout("req=%p req->r_linger=%d\n", req, req->r_linger);
@@ -1732,6 +1736,7 @@ int ceph_osdc_wait_request(struct ceph_osd_client *osdc,
17321736
__cancel_request(req);
17331737
__unregister_request(osdc, req);
17341738
mutex_unlock(&osdc->request_mutex);
1739+
complete_request(req);
17351740
dout("wait_request tid %llu canceled/timed out\n", req->r_tid);
17361741
return rc;
17371742
}

0 commit comments

Comments
 (0)