You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
switch ->get_link() to delayed_call, kill ->put_link()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
@@ -51,7 +51,6 @@ prototypes:
|
||||
struct inode *, struct dentry *, unsigned int);
|
||||
int (*readlink) (struct dentry *, char __user *,int);
|
||||
const char *(*get_link) (struct dentry *, struct inode *, void **);
|
||||
void (*put_link) (struct inode *, void *);
|
||||
void (*truncate) (struct inode *);
|
||||
int (*permission) (struct inode *, int, unsigned int);
|
||||
int (*get_acl)(struct inode *, int);
|
||||
@@ -84,7 +83,6 @@ rename: yes (all) (see below)
|
||||
rename2: yes (all) (see below)
|
||||
readlink: no
|
||||
get_link: no
|
||||
put_link: no
|
||||
setattr: yes
|
||||
permission: no (may not block if called in rcu-walk mode)
|
||||
get_acl: no
|
||||
|
||||
@@ -515,3 +515,9 @@ in your dentry operations instead.
|
||||
* ->get_link() gets inode as a separate argument
|
||||
* ->get_link() may be called in RCU mode - in that case NULL
|
||||
dentry is passed
|
||||
--
|
||||
[mandatory]
|
||||
->get_link() gets struct delayed_call *done now, and should do
|
||||
set_delayed_call() where it used to set *cookie.
|
||||
->put_link() is gone - just give the destructor to set_delayed_call()
|
||||
in ->get_link().
|
||||
|
||||
@@ -350,8 +350,8 @@ struct inode_operations {
|
||||
int (*rename2) (struct inode *, struct dentry *,
|
||||
struct inode *, struct dentry *, unsigned int);
|
||||
int (*readlink) (struct dentry *, char __user *,int);
|
||||
const char *(*follow_link) (struct dentry *, void **);
|
||||
void (*put_link) (struct inode *, void *);
|
||||
const char *(*get_link) (struct dentry *, struct inode *,
|
||||
struct delayed_call *);
|
||||
int (*permission) (struct inode *, int);
|
||||
int (*get_acl)(struct inode *, int);
|
||||
int (*setattr) (struct dentry *, struct iattr *);
|
||||
@@ -434,20 +434,19 @@ otherwise noted.
|
||||
readlink: called by the readlink(2) system call. Only required if
|
||||
you want to support reading symbolic links
|
||||
|
||||
follow_link: called by the VFS to follow a symbolic link to the
|
||||
get_link: called by the VFS to follow a symbolic link to the
|
||||
inode it points to. Only required if you want to support
|
||||
symbolic links. This method returns the symlink body
|
||||
to traverse (and possibly resets the current position with
|
||||
nd_jump_link()). If the body won't go away until the inode
|
||||
is gone, nothing else is needed; if it needs to be otherwise
|
||||
pinned, the data needed to release whatever we'd grabbed
|
||||
is to be stored in void * variable passed by address to
|
||||
follow_link() instance.
|
||||
|
||||
put_link: called by the VFS to release resources allocated by
|
||||
follow_link(). The cookie stored by follow_link() is passed
|
||||
to this method as the last parameter; only called when
|
||||
cookie isn't NULL.
|
||||
pinned, arrange for its release by having get_link(..., ..., done)
|
||||
do set_delayed_call(done, destructor, argument).
|
||||
In that case destructor(argument) will be called once VFS is
|
||||
done with the body you've returned.
|
||||
May be called in RCU mode; that is indicated by NULL dentry
|
||||
argument. If request can't be handled without leaving RCU mode,
|
||||
have it return ERR_PTR(-ECHILD).
|
||||
|
||||
permission: called by the VFS to check for access rights on a POSIX-like
|
||||
filesystem.
|
||||
|
||||
@@ -118,8 +118,14 @@ failed:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void ll_put_link(void *p)
|
||||
{
|
||||
ptlrpc_req_finished(p);
|
||||
}
|
||||
|
||||
static const char *ll_get_link(struct dentry *dentry,
|
||||
struct inode *inode, void **cookie)
|
||||
struct inode *inode,
|
||||
struct delayed_call *done)
|
||||
{
|
||||
struct ptlrpc_request *request = NULL;
|
||||
int rc;
|
||||
@@ -137,22 +143,16 @@ static const char *ll_get_link(struct dentry *dentry,
|
||||
}
|
||||
|
||||
/* symname may contain a pointer to the request message buffer,
|
||||
* we delay request releasing until ll_put_link then.
|
||||
* we delay request releasing then.
|
||||
*/
|
||||
*cookie = request;
|
||||
set_delayed_call(done, ll_put_link, request);
|
||||
return symname;
|
||||
}
|
||||
|
||||
static void ll_put_link(struct inode *unused, void *cookie)
|
||||
{
|
||||
ptlrpc_req_finished(cookie);
|
||||
}
|
||||
|
||||
struct inode_operations ll_fast_symlink_inode_operations = {
|
||||
.readlink = generic_readlink,
|
||||
.setattr = ll_setattr,
|
||||
.get_link = ll_get_link,
|
||||
.put_link = ll_put_link,
|
||||
.getattr = ll_getattr,
|
||||
.permission = ll_inode_permission,
|
||||
.setxattr = ll_setxattr,
|
||||
|
||||
+5
-4
@@ -1226,11 +1226,12 @@ ino_t v9fs_qid2ino(struct p9_qid *qid)
|
||||
* v9fs_vfs_get_link - follow a symlink path
|
||||
* @dentry: dentry for symlink
|
||||
* @inode: inode for symlink
|
||||
* @cookie: place to pass the data to put_link()
|
||||
* @done: delayed call for when we are done with the return value
|
||||
*/
|
||||
|
||||
static const char *v9fs_vfs_get_link(struct dentry *dentry,
|
||||
struct inode *inode, void **cookie)
|
||||
struct inode *inode,
|
||||
struct delayed_call *done)
|
||||
{
|
||||
struct v9fs_session_info *v9ses;
|
||||
struct p9_fid *fid;
|
||||
@@ -1266,7 +1267,8 @@ static const char *v9fs_vfs_get_link(struct dentry *dentry,
|
||||
|
||||
p9stat_free(st);
|
||||
kfree(st);
|
||||
return *cookie = res;
|
||||
set_delayed_call(done, kfree_link, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1460,7 +1462,6 @@ static const struct inode_operations v9fs_file_inode_operations = {
|
||||
static const struct inode_operations v9fs_symlink_inode_operations = {
|
||||
.readlink = generic_readlink,
|
||||
.get_link = v9fs_vfs_get_link,
|
||||
.put_link = kfree_put_link,
|
||||
.getattr = v9fs_vfs_getattr,
|
||||
.setattr = v9fs_vfs_setattr,
|
||||
};
|
||||
|
||||
@@ -902,12 +902,13 @@ error:
|
||||
* v9fs_vfs_get_link_dotl - follow a symlink path
|
||||
* @dentry: dentry for symlink
|
||||
* @inode: inode for symlink
|
||||
* @cookie: place to pass the data to put_link()
|
||||
* @done: destructor for return value
|
||||
*/
|
||||
|
||||
static const char *
|
||||
v9fs_vfs_get_link_dotl(struct dentry *dentry,
|
||||
struct inode *inode, void **cookie)
|
||||
struct inode *inode,
|
||||
struct delayed_call *done)
|
||||
{
|
||||
struct p9_fid *fid;
|
||||
char *target;
|
||||
@@ -924,7 +925,8 @@ v9fs_vfs_get_link_dotl(struct dentry *dentry,
|
||||
retval = p9_client_readlink(fid, &target);
|
||||
if (retval)
|
||||
return ERR_PTR(retval);
|
||||
return *cookie = target;
|
||||
set_delayed_call(done, kfree_link, target);
|
||||
return target;
|
||||
}
|
||||
|
||||
int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode)
|
||||
@@ -991,7 +993,6 @@ const struct inode_operations v9fs_file_inode_operations_dotl = {
|
||||
const struct inode_operations v9fs_symlink_inode_operations_dotl = {
|
||||
.readlink = generic_readlink,
|
||||
.get_link = v9fs_vfs_get_link_dotl,
|
||||
.put_link = kfree_put_link,
|
||||
.getattr = v9fs_vfs_getattr_dotl,
|
||||
.setattr = v9fs_vfs_setattr_dotl,
|
||||
.setxattr = generic_setxattr,
|
||||
|
||||
@@ -72,6 +72,5 @@ const struct address_space_operations affs_symlink_aops = {
|
||||
const struct inode_operations affs_symlink_inode_operations = {
|
||||
.readlink = generic_readlink,
|
||||
.get_link = page_get_link,
|
||||
.put_link = page_put_link,
|
||||
.setattr = affs_notify_change,
|
||||
};
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
#include "autofs_i.h"
|
||||
|
||||
static const char *autofs4_get_link(struct dentry *dentry,
|
||||
struct inode *inode, void **cookie)
|
||||
struct inode *inode,
|
||||
struct delayed_call *done)
|
||||
{
|
||||
struct autofs_sb_info *sbi;
|
||||
struct autofs_info *ino;
|
||||
|
||||
@@ -10097,7 +10097,6 @@ static const struct inode_operations btrfs_special_inode_operations = {
|
||||
static const struct inode_operations btrfs_symlink_inode_operations = {
|
||||
.readlink = generic_readlink,
|
||||
.get_link = page_get_link,
|
||||
.put_link = page_put_link,
|
||||
.getattr = btrfs_getattr,
|
||||
.setattr = btrfs_setattr,
|
||||
.permission = btrfs_permission,
|
||||
|
||||
@@ -901,7 +901,6 @@ const struct inode_operations cifs_file_inode_ops = {
|
||||
const struct inode_operations cifs_symlink_inode_ops = {
|
||||
.readlink = generic_readlink,
|
||||
.get_link = cifs_get_link,
|
||||
.put_link = kfree_put_link,
|
||||
.permission = cifs_permission,
|
||||
/* BB add the following two eventually */
|
||||
/* revalidate: cifs_revalidate,
|
||||
|
||||
+2
-1
@@ -120,7 +120,8 @@ extern struct vfsmount *cifs_dfs_d_automount(struct path *path);
|
||||
#endif
|
||||
|
||||
/* Functions related to symlinks */
|
||||
extern const char *cifs_get_link(struct dentry *, struct inode *, void **);
|
||||
extern const char *cifs_get_link(struct dentry *, struct inode *,
|
||||
struct delayed_call *);
|
||||
extern int cifs_symlink(struct inode *inode, struct dentry *direntry,
|
||||
const char *symname);
|
||||
extern int cifs_removexattr(struct dentry *, const char *);
|
||||
|
||||
+4
-2
@@ -627,7 +627,8 @@ cifs_hl_exit:
|
||||
}
|
||||
|
||||
const char *
|
||||
cifs_get_link(struct dentry *direntry, struct inode *inode, void **cookie)
|
||||
cifs_get_link(struct dentry *direntry, struct inode *inode,
|
||||
struct delayed_call *done)
|
||||
{
|
||||
int rc = -ENOMEM;
|
||||
unsigned int xid;
|
||||
@@ -680,7 +681,8 @@ cifs_get_link(struct dentry *direntry, struct inode *inode, void **cookie)
|
||||
kfree(target_path);
|
||||
return ERR_PTR(rc);
|
||||
}
|
||||
return *cookie = target_path;
|
||||
set_delayed_call(done, kfree_link, target_path);
|
||||
return target_path;
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -19,7 +19,6 @@ static inline int coda_fideq(struct CodaFid *fid1, struct CodaFid *fid2)
|
||||
static const struct inode_operations coda_symlink_inode_operations = {
|
||||
.readlink = generic_readlink,
|
||||
.get_link = page_get_link,
|
||||
.put_link = page_put_link,
|
||||
.setattr = coda_setattr,
|
||||
};
|
||||
|
||||
|
||||
@@ -280,31 +280,32 @@ static int configfs_getlink(struct dentry *dentry, char * path)
|
||||
}
|
||||
|
||||
static const char *configfs_get_link(struct dentry *dentry,
|
||||
struct inode *inode, void **cookie)
|
||||
struct inode *inode,
|
||||
struct delayed_call *done)
|
||||
{
|
||||
char *page;
|
||||
char *body;
|
||||
int error;
|
||||
|
||||
if (!dentry)
|
||||
return ERR_PTR(-ECHILD);
|
||||
|
||||
page = kzalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
if (!page)
|
||||
body = kzalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
if (!body)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
error = configfs_getlink(dentry, page);
|
||||
error = configfs_getlink(dentry, body);
|
||||
if (!error) {
|
||||
return *cookie = page;
|
||||
set_delayed_call(done, kfree_link, body);
|
||||
return body;
|
||||
}
|
||||
|
||||
kfree(page);
|
||||
kfree(body);
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
|
||||
const struct inode_operations configfs_symlink_inode_operations = {
|
||||
.get_link = configfs_get_link,
|
||||
.readlink = generic_readlink,
|
||||
.put_link = kfree_put_link,
|
||||
.setattr = configfs_setattr,
|
||||
};
|
||||
|
||||
|
||||
+4
-3
@@ -675,7 +675,8 @@ out:
|
||||
}
|
||||
|
||||
static const char *ecryptfs_get_link(struct dentry *dentry,
|
||||
struct inode *inode, void **cookie)
|
||||
struct inode *inode,
|
||||
struct delayed_call *done)
|
||||
{
|
||||
size_t len;
|
||||
char *buf;
|
||||
@@ -689,7 +690,8 @@ static const char *ecryptfs_get_link(struct dentry *dentry,
|
||||
fsstack_copy_attr_atime(d_inode(dentry),
|
||||
d_inode(ecryptfs_dentry_to_lower(dentry)));
|
||||
buf[len] = '\0';
|
||||
return *cookie = buf;
|
||||
set_delayed_call(done, kfree_link, buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1102,7 +1104,6 @@ out:
|
||||
const struct inode_operations ecryptfs_symlink_iops = {
|
||||
.readlink = generic_readlink,
|
||||
.get_link = ecryptfs_get_link,
|
||||
.put_link = kfree_put_link,
|
||||
.permission = ecryptfs_permission,
|
||||
.setattr = ecryptfs_setattr,
|
||||
.getattr = ecryptfs_getattr_link,
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
const struct inode_operations ext2_symlink_inode_operations = {
|
||||
.readlink = generic_readlink,
|
||||
.get_link = page_get_link,
|
||||
.put_link = page_put_link,
|
||||
.setattr = ext2_setattr,
|
||||
#ifdef CONFIG_EXT2_FS_XATTR
|
||||
.setxattr = generic_setxattr,
|
||||
|
||||
+4
-4
@@ -24,7 +24,8 @@
|
||||
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
static const char *ext4_encrypted_get_link(struct dentry *dentry,
|
||||
struct inode *inode, void **cookie)
|
||||
struct inode *inode,
|
||||
struct delayed_call *done)
|
||||
{
|
||||
struct page *cpage = NULL;
|
||||
char *caddr, *paddr = NULL;
|
||||
@@ -80,7 +81,8 @@ static const char *ext4_encrypted_get_link(struct dentry *dentry,
|
||||
paddr[res] = '\0';
|
||||
if (cpage)
|
||||
page_cache_release(cpage);
|
||||
return *cookie = paddr;
|
||||
set_delayed_call(done, kfree_link, paddr);
|
||||
return paddr;
|
||||
errout:
|
||||
if (cpage)
|
||||
page_cache_release(cpage);
|
||||
@@ -91,7 +93,6 @@ errout:
|
||||
const struct inode_operations ext4_encrypted_symlink_inode_operations = {
|
||||
.readlink = generic_readlink,
|
||||
.get_link = ext4_encrypted_get_link,
|
||||
.put_link = kfree_put_link,
|
||||
.setattr = ext4_setattr,
|
||||
.setxattr = generic_setxattr,
|
||||
.getxattr = generic_getxattr,
|
||||
@@ -103,7 +104,6 @@ const struct inode_operations ext4_encrypted_symlink_inode_operations = {
|
||||
const struct inode_operations ext4_symlink_inode_operations = {
|
||||
.readlink = generic_readlink,
|
||||
.get_link = page_get_link,
|
||||
.put_link = page_put_link,
|
||||
.setattr = ext4_setattr,
|
||||
.setxattr = generic_setxattr,
|
||||
.getxattr = generic_getxattr,
|
||||
|
||||
+9
-7
@@ -316,12 +316,14 @@ fail:
|
||||
}
|
||||
|
||||
static const char *f2fs_get_link(struct dentry *dentry,
|
||||
struct inode *inode, void **cookie)
|
||||
struct inode *inode,
|
||||
struct delayed_call *done)
|
||||
{
|
||||
const char *link = page_get_link(dentry, inode, cookie);
|
||||
const char *link = page_get_link(dentry, inode, done);
|
||||
if (!IS_ERR(link) && !*link) {
|
||||
/* this is broken symlink case */
|
||||
page_put_link(NULL, *cookie);
|
||||
do_delayed_call(done);
|
||||
clear_delayed_call(done);
|
||||
link = ERR_PTR(-ENOENT);
|
||||
}
|
||||
return link;
|
||||
@@ -926,7 +928,8 @@ static int f2fs_rename2(struct inode *old_dir, struct dentry *old_dentry,
|
||||
|
||||
#ifdef CONFIG_F2FS_FS_ENCRYPTION
|
||||
static const char *f2fs_encrypted_get_link(struct dentry *dentry,
|
||||
struct inode *inode, void **cookie)
|
||||
struct inode *inode,
|
||||
struct delayed_call *done)
|
||||
{
|
||||
struct page *cpage = NULL;
|
||||
char *caddr, *paddr = NULL;
|
||||
@@ -988,7 +991,8 @@ static const char *f2fs_encrypted_get_link(struct dentry *dentry,
|
||||
paddr[res] = '\0';
|
||||
|
||||
page_cache_release(cpage);
|
||||
return *cookie = paddr;
|
||||
set_delayed_call(done, kfree_link, paddr);
|
||||
return paddr;
|
||||
errout:
|
||||
kfree(cstr.name);
|
||||
f2fs_fname_crypto_free_buffer(&pstr);
|
||||
@@ -999,7 +1003,6 @@ errout:
|
||||
const struct inode_operations f2fs_encrypted_symlink_inode_operations = {
|
||||
.readlink = generic_readlink,
|
||||
.get_link = f2fs_encrypted_get_link,
|
||||
.put_link = kfree_put_link,
|
||||
.getattr = f2fs_getattr,
|
||||
.setattr = f2fs_setattr,
|
||||
.setxattr = generic_setxattr,
|
||||
@@ -1035,7 +1038,6 @@ const struct inode_operations f2fs_dir_inode_operations = {
|
||||
const struct inode_operations f2fs_symlink_inode_operations = {
|
||||
.readlink = generic_readlink,
|
||||
.get_link = f2fs_get_link,
|
||||
.put_link = page_put_link,
|
||||
.getattr = f2fs_getattr,
|
||||
.setattr = f2fs_setattr,
|
||||
#ifdef CONFIG_F2FS_FS_XATTR
|
||||
|
||||
+3
-3
@@ -1366,7 +1366,8 @@ static int fuse_readdir(struct file *file, struct dir_context *ctx)
|
||||
}
|
||||
|
||||
static const char *fuse_get_link(struct dentry *dentry,
|
||||
struct inode *inode, void **cookie)
|
||||
struct inode *inode,
|
||||
struct delayed_call *done)
|
||||
{
|
||||
struct fuse_conn *fc = get_fuse_conn(inode);
|
||||
FUSE_ARGS(args);
|
||||
@@ -1392,7 +1393,7 @@ static const char *fuse_get_link(struct dentry *dentry,
|
||||
link = ERR_PTR(ret);
|
||||
} else {
|
||||
link[ret] = '\0';
|
||||
*cookie = link;
|
||||
set_delayed_call(done, kfree_link, link);
|
||||
}
|
||||
fuse_invalidate_atime(inode);
|
||||
return link;
|
||||
@@ -1913,7 +1914,6 @@ static const struct inode_operations fuse_common_inode_operations = {
|
||||
static const struct inode_operations fuse_symlink_inode_operations = {
|
||||
.setattr = fuse_setattr,
|
||||
.get_link = fuse_get_link,
|
||||
.put_link = kfree_put_link,
|
||||
.readlink = generic_readlink,
|
||||
.getattr = fuse_getattr,
|
||||
.setxattr = fuse_setxattr,
|
||||
|
||||
+4
-4
@@ -1715,7 +1715,7 @@ static int gfs2_rename2(struct inode *odir, struct dentry *odentry,
|
||||
* gfs2_get_link - Follow a symbolic link
|
||||
* @dentry: The dentry of the link
|
||||
* @inode: The inode of the link
|
||||
* @cookie: place to store the information for ->put_link()
|
||||
* @done: destructor for return value
|
||||
*
|
||||
* This can handle symlinks of any size.
|
||||
*
|
||||
@@ -1723,7 +1723,8 @@ static int gfs2_rename2(struct inode *odir, struct dentry *odentry,
|
||||
*/
|
||||
|
||||
static const char *gfs2_get_link(struct dentry *dentry,
|
||||
struct inode *inode, void **cookie)
|
||||
struct inode *inode,
|
||||
struct delayed_call *done)
|
||||
{
|
||||
struct gfs2_inode *ip = GFS2_I(inode);
|
||||
struct gfs2_holder i_gh;
|
||||
@@ -1764,7 +1765,7 @@ static const char *gfs2_get_link(struct dentry *dentry,
|
||||
out:
|
||||
gfs2_glock_dq_uninit(&i_gh);
|
||||
if (!IS_ERR(buf))
|
||||
*cookie = buf;
|
||||
set_delayed_call(done, kfree_link, buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
@@ -2138,7 +2139,6 @@ const struct inode_operations gfs2_dir_iops = {
|
||||
const struct inode_operations gfs2_symlink_iops = {
|
||||
.readlink = generic_readlink,
|
||||
.get_link = gfs2_get_link,
|
||||
.put_link = kfree_put_link,
|
||||
.permission = gfs2_permission,
|
||||
.setattr = gfs2_setattr,
|
||||
.getattr = gfs2_getattr,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user