mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-04-13 09:59:31 +00:00
afs: Locally initialise the contents of a new symlink on creation
Since we know what the contents of a symlink will be when we create it on the server, initialise its contents locally too to avoid the need to download it. Signed-off-by: David Howells <dhowells@redhat.com> Link: https://lore.kernel.org/r/20241216204124.3752367-31-dhowells@redhat.com cc: Marc Dionne <marc.dionne@auristor.com> cc: linux-afs@lists.infradead.org Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
parent
a5b5beebcf
commit
6698c02d64
5 changed files with 45 additions and 8 deletions
|
@ -1276,6 +1276,8 @@ static void afs_vnode_new_inode(struct afs_operation *op)
|
|||
set_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags);
|
||||
if (S_ISDIR(inode->i_mode))
|
||||
afs_mkdir_init_dir(vnode, dvp->vnode);
|
||||
else if (S_ISLNK(inode->i_mode))
|
||||
afs_init_new_symlink(vnode, op);
|
||||
if (!afs_op_error(op))
|
||||
afs_cache_permit(vnode, op->key, vnode->cb_break, &vp->scb);
|
||||
d_instantiate(op->dentry, inode);
|
||||
|
|
|
@ -25,6 +25,24 @@
|
|||
#include "internal.h"
|
||||
#include "afs_fs.h"
|
||||
|
||||
void afs_init_new_symlink(struct afs_vnode *vnode, struct afs_operation *op)
|
||||
{
|
||||
size_t size = strlen(op->create.symlink) + 1;
|
||||
size_t dsize = 0;
|
||||
char *p;
|
||||
|
||||
if (netfs_alloc_folioq_buffer(NULL, &vnode->directory, &dsize, size,
|
||||
mapping_gfp_mask(vnode->netfs.inode.i_mapping)) < 0)
|
||||
return;
|
||||
|
||||
vnode->directory_size = dsize;
|
||||
p = kmap_local_folio(folioq_folio(vnode->directory, 0), 0);
|
||||
memcpy(p, op->create.symlink, size);
|
||||
kunmap_local(p);
|
||||
set_bit(AFS_VNODE_DIR_READ, &vnode->flags);
|
||||
netfs_single_mark_inode_dirty(&vnode->netfs.inode);
|
||||
}
|
||||
|
||||
static void afs_put_link(void *arg)
|
||||
{
|
||||
struct folio *folio = virt_to_folio(arg);
|
||||
|
@ -41,15 +59,31 @@ const char *afs_get_link(struct dentry *dentry, struct inode *inode,
|
|||
char *content;
|
||||
ssize_t ret;
|
||||
|
||||
if (atomic64_read(&vnode->cb_expires_at) == AFS_NO_CB_PROMISE ||
|
||||
!test_bit(AFS_VNODE_DIR_READ, &vnode->flags)) {
|
||||
if (!dentry)
|
||||
if (!dentry) {
|
||||
/* RCU pathwalk. */
|
||||
if (!test_bit(AFS_VNODE_DIR_READ, &vnode->flags) || !afs_check_validity(vnode))
|
||||
return ERR_PTR(-ECHILD);
|
||||
goto good;
|
||||
}
|
||||
|
||||
if (test_bit(AFS_VNODE_DIR_READ, &vnode->flags))
|
||||
goto fetch;
|
||||
|
||||
ret = afs_validate(vnode, NULL);
|
||||
if (ret < 0)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
if (!test_and_clear_bit(AFS_VNODE_ZAP_DATA, &vnode->flags) &&
|
||||
test_bit(AFS_VNODE_DIR_READ, &vnode->flags))
|
||||
goto good;
|
||||
|
||||
fetch:
|
||||
ret = afs_read_single(vnode, NULL);
|
||||
if (ret < 0)
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
set_bit(AFS_VNODE_DIR_READ, &vnode->flags);
|
||||
|
||||
good:
|
||||
folio = folioq_folio(vnode->directory, 0);
|
||||
folio_get(folio);
|
||||
content = kmap_local_folio(folio, 0);
|
||||
|
|
|
@ -1221,6 +1221,7 @@ extern void afs_fs_probe_cleanup(struct afs_net *);
|
|||
*/
|
||||
extern const struct afs_operation_ops afs_fetch_status_operation;
|
||||
|
||||
void afs_init_new_symlink(struct afs_vnode *vnode, struct afs_operation *op);
|
||||
const char *afs_get_link(struct dentry *dentry, struct inode *inode,
|
||||
struct delayed_call *callback);
|
||||
int afs_readlink(struct dentry *dentry, char __user *buffer, int buflen);
|
||||
|
|
|
@ -210,7 +210,7 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
|
|||
|
||||
do {
|
||||
struct netfs_io_subrequest *subreq;
|
||||
enum netfs_io_source source = NETFS_DOWNLOAD_FROM_SERVER;
|
||||
enum netfs_io_source source = NETFS_SOURCE_UNKNOWN;
|
||||
ssize_t slice;
|
||||
|
||||
subreq = netfs_alloc_subrequest(rreq);
|
||||
|
|
|
@ -97,7 +97,7 @@ static int netfs_single_dispatch_read(struct netfs_io_request *rreq)
|
|||
if (!subreq)
|
||||
return -ENOMEM;
|
||||
|
||||
subreq->source = NETFS_DOWNLOAD_FROM_SERVER;
|
||||
subreq->source = NETFS_SOURCE_UNKNOWN;
|
||||
subreq->start = 0;
|
||||
subreq->len = rreq->len;
|
||||
subreq->io_iter = rreq->buffer.iter;
|
||||
|
|
Loading…
Add table
Reference in a new issue