Skip to content

Commit

Permalink
Merge tag 'ceph-for-5.19-rc7' of https://github.com/ceph/ceph-client
Browse files Browse the repository at this point in the history
Pull ceph fix from Ilya Dryomov:
 "A folio locking fixup that Xiubo and David cooperated on, marked for
  stable. Most of it is in netfs but I picked it up into ceph tree on
  agreement with David"

* tag 'ceph-for-5.19-rc7' of https://github.com/ceph/ceph-client:
  netfs: do not unlock and put the folio twice
  • Loading branch information
Linus Torvalds committed Jul 15, 2022
2 parents 8006112 + fac47b4 commit 1ce9d79
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 17 deletions.
8 changes: 5 additions & 3 deletions Documentation/filesystems/netfs_library.rst
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ through which it can issue requests and negotiate::
void (*issue_read)(struct netfs_io_subrequest *subreq);
bool (*is_still_valid)(struct netfs_io_request *rreq);
int (*check_write_begin)(struct file *file, loff_t pos, unsigned len,
struct folio *folio, void **_fsdata);
struct folio **foliop, void **_fsdata);
void (*done)(struct netfs_io_request *rreq);
};

Expand Down Expand Up @@ -381,8 +381,10 @@ The operations are as follows:
allocated/grabbed the folio to be modified to allow the filesystem to flush
conflicting state before allowing it to be modified.

It should return 0 if everything is now fine, -EAGAIN if the folio should be
regrabbed and any other error code to abort the operation.
It may unlock and discard the folio it was given and set the caller's folio
pointer to NULL. It should return 0 if everything is now fine (``*foliop``
left set) or the op should be retried (``*foliop`` cleared) and any other
error code to abort the operation.

* ``done``

Expand Down
2 changes: 1 addition & 1 deletion fs/afs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ static int afs_begin_cache_operation(struct netfs_io_request *rreq)
}

static int afs_check_write_begin(struct file *file, loff_t pos, unsigned len,
struct folio *folio, void **_fsdata)
struct folio **foliop, void **_fsdata)
{
struct afs_vnode *vnode = AFS_FS_I(file_inode(file));

Expand Down
11 changes: 6 additions & 5 deletions fs/ceph/addr.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
(CONGESTION_ON_THRESH(congestion_kb) >> 2))

static int ceph_netfs_check_write_begin(struct file *file, loff_t pos, unsigned int len,
struct folio *folio, void **_fsdata);
struct folio **foliop, void **_fsdata);

static inline struct ceph_snap_context *page_snap_context(struct page *page)
{
Expand Down Expand Up @@ -1288,18 +1288,19 @@ ceph_find_incompatible(struct page *page)
}

static int ceph_netfs_check_write_begin(struct file *file, loff_t pos, unsigned int len,
struct folio *folio, void **_fsdata)
struct folio **foliop, void **_fsdata)
{
struct inode *inode = file_inode(file);
struct ceph_inode_info *ci = ceph_inode(inode);
struct ceph_snap_context *snapc;

snapc = ceph_find_incompatible(folio_page(folio, 0));
snapc = ceph_find_incompatible(folio_page(*foliop, 0));
if (snapc) {
int r;

folio_unlock(folio);
folio_put(folio);
folio_unlock(*foliop);
folio_put(*foliop);
*foliop = NULL;
if (IS_ERR(snapc))
return PTR_ERR(snapc);

Expand Down
17 changes: 10 additions & 7 deletions fs/netfs/buffered_read.c
Original file line number Diff line number Diff line change
Expand Up @@ -319,8 +319,9 @@ static bool netfs_skip_folio_read(struct folio *folio, loff_t pos, size_t len,
* conflicting writes once the folio is grabbed and locked. It is passed a
* pointer to the fsdata cookie that gets returned to the VM to be passed to
* write_end. It is permitted to sleep. It should return 0 if the request
* should go ahead; unlock the folio and return -EAGAIN to cause the folio to
* be regot; or return an error.
* should go ahead or it may return an error. It may also unlock and put the
* folio, provided it sets ``*foliop`` to NULL, in which case a return of 0
* will cause the folio to be re-got and the process to be retried.
*
* The calling netfs must initialise a netfs context contiguous to the vfs
* inode before calling this.
Expand Down Expand Up @@ -348,13 +349,13 @@ int netfs_write_begin(struct netfs_inode *ctx,

if (ctx->ops->check_write_begin) {
/* Allow the netfs (eg. ceph) to flush conflicts. */
ret = ctx->ops->check_write_begin(file, pos, len, folio, _fsdata);
ret = ctx->ops->check_write_begin(file, pos, len, &folio, _fsdata);
if (ret < 0) {
trace_netfs_failure(NULL, NULL, ret, netfs_fail_check_write_begin);
if (ret == -EAGAIN)
goto retry;
goto error;
}
if (!folio)
goto retry;
}

if (folio_test_uptodate(folio))
Expand Down Expand Up @@ -416,8 +417,10 @@ int netfs_write_begin(struct netfs_inode *ctx,
error_put:
netfs_put_request(rreq, false, netfs_rreq_trace_put_failed);
error:
folio_unlock(folio);
folio_put(folio);
if (folio) {
folio_unlock(folio);
folio_put(folio);
}
_leave(" = %d", ret);
return ret;
}
Expand Down
2 changes: 1 addition & 1 deletion include/linux/netfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ struct netfs_request_ops {
void (*issue_read)(struct netfs_io_subrequest *subreq);
bool (*is_still_valid)(struct netfs_io_request *rreq);
int (*check_write_begin)(struct file *file, loff_t pos, unsigned len,
struct folio *folio, void **_fsdata);
struct folio **foliop, void **_fsdata);
void (*done)(struct netfs_io_request *rreq);
};

Expand Down

0 comments on commit 1ce9d79

Please sign in to comment.