mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
Merge 79a7216204 ("Merge tag 'xfs-5.16-fixes-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux") into android-mainline
Steps on the way to 5.16-rc4 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I0ffbfbf90e6609c741ae848c30dc245b421d07f9
This commit is contained in:
@@ -2103,7 +2103,7 @@ static int loop_control_remove(int idx)
|
||||
int ret;
|
||||
|
||||
if (idx < 0) {
|
||||
pr_warn("deleting an unspecified loop device is not supported.\n");
|
||||
pr_warn_once("deleting an unspecified loop device is not supported.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
@@ -5095,14 +5095,9 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
/* NPort Recovery mode or node is just allocated */
|
||||
if (!lpfc_nlp_not_used(ndlp)) {
|
||||
/* A LOGO is completing and the node is in NPR state.
|
||||
* If this a fabric node that cleared its transport
|
||||
* registration, release the rpi.
|
||||
* Just unregister the RPI because the node is still
|
||||
* required.
|
||||
*/
|
||||
spin_lock_irq(&ndlp->lock);
|
||||
ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
|
||||
if (phba->sli_rev == LPFC_SLI_REV4)
|
||||
ndlp->nlp_flag |= NLP_RELEASE_RPI;
|
||||
spin_unlock_irq(&ndlp->lock);
|
||||
lpfc_unreg_rpi(vport, ndlp);
|
||||
} else {
|
||||
/* Indicate the node has already released, should
|
||||
|
||||
@@ -421,6 +421,13 @@ static int ufs_intel_lkf_init(struct ufs_hba *hba)
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ufs_intel_adl_init(struct ufs_hba *hba)
|
||||
{
|
||||
hba->nop_out_timeout = 200;
|
||||
hba->quirks |= UFSHCD_QUIRK_BROKEN_AUTO_HIBERN8;
|
||||
return ufs_intel_common_init(hba);
|
||||
}
|
||||
|
||||
static struct ufs_hba_variant_ops ufs_intel_cnl_hba_vops = {
|
||||
.name = "intel-pci",
|
||||
.init = ufs_intel_common_init,
|
||||
@@ -449,6 +456,15 @@ static struct ufs_hba_variant_ops ufs_intel_lkf_hba_vops = {
|
||||
.device_reset = ufs_intel_device_reset,
|
||||
};
|
||||
|
||||
static struct ufs_hba_variant_ops ufs_intel_adl_hba_vops = {
|
||||
.name = "intel-pci",
|
||||
.init = ufs_intel_adl_init,
|
||||
.exit = ufs_intel_common_exit,
|
||||
.link_startup_notify = ufs_intel_link_startup_notify,
|
||||
.resume = ufs_intel_resume,
|
||||
.device_reset = ufs_intel_device_reset,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int ufshcd_pci_restore(struct device *dev)
|
||||
{
|
||||
@@ -563,6 +579,8 @@ static const struct pci_device_id ufshcd_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0x4B41), (kernel_ulong_t)&ufs_intel_ehl_hba_vops },
|
||||
{ PCI_VDEVICE(INTEL, 0x4B43), (kernel_ulong_t)&ufs_intel_ehl_hba_vops },
|
||||
{ PCI_VDEVICE(INTEL, 0x98FA), (kernel_ulong_t)&ufs_intel_lkf_hba_vops },
|
||||
{ PCI_VDEVICE(INTEL, 0x51FF), (kernel_ulong_t)&ufs_intel_adl_hba_vops },
|
||||
{ PCI_VDEVICE(INTEL, 0x54FF), (kernel_ulong_t)&ufs_intel_adl_hba_vops },
|
||||
{ } /* terminate list */
|
||||
};
|
||||
|
||||
|
||||
@@ -1562,6 +1562,10 @@ smbd_connected:
|
||||
/* fscache server cookies are based on primary channel only */
|
||||
if (!CIFS_SERVER_IS_CHAN(tcp_ses))
|
||||
cifs_fscache_get_client_cookie(tcp_ses);
|
||||
#ifdef CONFIG_CIFS_FSCACHE
|
||||
else
|
||||
tcp_ses->fscache = tcp_ses->primary_server->fscache;
|
||||
#endif /* CONFIG_CIFS_FSCACHE */
|
||||
|
||||
/* queue echo request delayed work */
|
||||
queue_delayed_work(cifsiod_wq, &tcp_ses->echo, tcp_ses->echo_interval);
|
||||
@@ -3046,12 +3050,6 @@ static int mount_get_conns(struct mount_ctx *mnt_ctx)
|
||||
cifs_dbg(VFS, "read only mount of RW share\n");
|
||||
/* no need to log a RW mount of a typical RW share */
|
||||
}
|
||||
/*
|
||||
* The cookie is initialized from volume info returned above.
|
||||
* Inside cifs_fscache_get_super_cookie it checks
|
||||
* that we do not get super cookie twice.
|
||||
*/
|
||||
cifs_fscache_get_super_cookie(tcon);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3426,6 +3424,7 @@ static int connect_dfs_root(struct mount_ctx *mnt_ctx, struct dfs_cache_tgt_list
|
||||
*/
|
||||
mount_put_conns(mnt_ctx);
|
||||
mount_get_dfs_conns(mnt_ctx);
|
||||
set_root_ses(mnt_ctx);
|
||||
|
||||
full_path = build_unc_path_to_root(ctx, cifs_sb, true);
|
||||
if (IS_ERR(full_path))
|
||||
|
||||
@@ -16,14 +16,7 @@
|
||||
* Key layout of CIFS server cache index object
|
||||
*/
|
||||
struct cifs_server_key {
|
||||
struct {
|
||||
uint16_t family; /* address family */
|
||||
__be16 port; /* IP port */
|
||||
} hdr;
|
||||
union {
|
||||
struct in_addr ipv4_addr;
|
||||
struct in6_addr ipv6_addr;
|
||||
};
|
||||
__u64 conn_id;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
@@ -31,42 +24,23 @@ struct cifs_server_key {
|
||||
*/
|
||||
void cifs_fscache_get_client_cookie(struct TCP_Server_Info *server)
|
||||
{
|
||||
const struct sockaddr *sa = (struct sockaddr *) &server->dstaddr;
|
||||
const struct sockaddr_in *addr = (struct sockaddr_in *) sa;
|
||||
const struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) sa;
|
||||
struct cifs_server_key key;
|
||||
uint16_t key_len = sizeof(key.hdr);
|
||||
|
||||
memset(&key, 0, sizeof(key));
|
||||
|
||||
/*
|
||||
* Should not be a problem as sin_family/sin6_family overlays
|
||||
* sa_family field
|
||||
* Check if cookie was already initialized so don't reinitialize it.
|
||||
* In the future, as we integrate with newer fscache features,
|
||||
* we may want to instead add a check if cookie has changed
|
||||
*/
|
||||
key.hdr.family = sa->sa_family;
|
||||
switch (sa->sa_family) {
|
||||
case AF_INET:
|
||||
key.hdr.port = addr->sin_port;
|
||||
key.ipv4_addr = addr->sin_addr;
|
||||
key_len += sizeof(key.ipv4_addr);
|
||||
break;
|
||||
|
||||
case AF_INET6:
|
||||
key.hdr.port = addr6->sin6_port;
|
||||
key.ipv6_addr = addr6->sin6_addr;
|
||||
key_len += sizeof(key.ipv6_addr);
|
||||
break;
|
||||
|
||||
default:
|
||||
cifs_dbg(VFS, "Unknown network family '%d'\n", sa->sa_family);
|
||||
server->fscache = NULL;
|
||||
if (server->fscache)
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&key, 0, sizeof(key));
|
||||
key.conn_id = server->conn_id;
|
||||
|
||||
server->fscache =
|
||||
fscache_acquire_cookie(cifs_fscache_netfs.primary_index,
|
||||
&cifs_fscache_server_index_def,
|
||||
&key, key_len,
|
||||
&key, sizeof(key),
|
||||
NULL, 0,
|
||||
server, 0, true);
|
||||
cifs_dbg(FYI, "%s: (0x%p/0x%p)\n",
|
||||
@@ -92,7 +66,7 @@ void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon)
|
||||
* In the future, as we integrate with newer fscache features,
|
||||
* we may want to instead add a check if cookie has changed
|
||||
*/
|
||||
if (tcon->fscache == NULL)
|
||||
if (tcon->fscache)
|
||||
return;
|
||||
|
||||
sharename = extract_sharename(tcon->treeName);
|
||||
|
||||
@@ -1376,6 +1376,13 @@ iget_no_retry:
|
||||
inode = ERR_PTR(rc);
|
||||
}
|
||||
|
||||
/*
|
||||
* The cookie is initialized from volume info returned above.
|
||||
* Inside cifs_fscache_get_super_cookie it checks
|
||||
* that we do not get super cookie twice.
|
||||
*/
|
||||
cifs_fscache_get_super_cookie(tcon);
|
||||
|
||||
out:
|
||||
kfree(path);
|
||||
free_xid(xid);
|
||||
|
||||
@@ -1857,7 +1857,6 @@ void gfs2_glock_dq_m(unsigned int num_gh, struct gfs2_holder *ghs)
|
||||
|
||||
void gfs2_glock_cb(struct gfs2_glock *gl, unsigned int state)
|
||||
{
|
||||
struct gfs2_holder mock_gh = { .gh_gl = gl, .gh_state = state, };
|
||||
unsigned long delay = 0;
|
||||
unsigned long holdtime;
|
||||
unsigned long now = jiffies;
|
||||
@@ -1890,8 +1889,13 @@ void gfs2_glock_cb(struct gfs2_glock *gl, unsigned int state)
|
||||
* keep the glock until the last strong holder is done with it.
|
||||
*/
|
||||
if (!find_first_strong_holder(gl)) {
|
||||
if (state == LM_ST_UNLOCKED)
|
||||
mock_gh.gh_state = LM_ST_EXCLUSIVE;
|
||||
struct gfs2_holder mock_gh = {
|
||||
.gh_gl = gl,
|
||||
.gh_state = (state == LM_ST_UNLOCKED) ?
|
||||
LM_ST_EXCLUSIVE : state,
|
||||
.gh_iflags = BIT(HIF_HOLDER)
|
||||
};
|
||||
|
||||
demote_incompat_holders(gl, &mock_gh);
|
||||
}
|
||||
handle_callback(gl, state, delay, true);
|
||||
|
||||
109
fs/gfs2/inode.c
109
fs/gfs2/inode.c
@@ -40,37 +40,6 @@ static const struct inode_operations gfs2_file_iops;
|
||||
static const struct inode_operations gfs2_dir_iops;
|
||||
static const struct inode_operations gfs2_symlink_iops;
|
||||
|
||||
static int iget_test(struct inode *inode, void *opaque)
|
||||
{
|
||||
u64 no_addr = *(u64 *)opaque;
|
||||
|
||||
return GFS2_I(inode)->i_no_addr == no_addr;
|
||||
}
|
||||
|
||||
static int iget_set(struct inode *inode, void *opaque)
|
||||
{
|
||||
u64 no_addr = *(u64 *)opaque;
|
||||
|
||||
GFS2_I(inode)->i_no_addr = no_addr;
|
||||
inode->i_ino = no_addr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr)
|
||||
{
|
||||
struct inode *inode;
|
||||
|
||||
repeat:
|
||||
inode = iget5_locked(sb, no_addr, iget_test, iget_set, &no_addr);
|
||||
if (!inode)
|
||||
return inode;
|
||||
if (is_bad_inode(inode)) {
|
||||
iput(inode);
|
||||
goto repeat;
|
||||
}
|
||||
return inode;
|
||||
}
|
||||
|
||||
/**
|
||||
* gfs2_set_iop - Sets inode operations
|
||||
* @inode: The inode with correct i_mode filled in
|
||||
@@ -104,6 +73,22 @@ static void gfs2_set_iop(struct inode *inode)
|
||||
}
|
||||
}
|
||||
|
||||
static int iget_test(struct inode *inode, void *opaque)
|
||||
{
|
||||
u64 no_addr = *(u64 *)opaque;
|
||||
|
||||
return GFS2_I(inode)->i_no_addr == no_addr;
|
||||
}
|
||||
|
||||
static int iget_set(struct inode *inode, void *opaque)
|
||||
{
|
||||
u64 no_addr = *(u64 *)opaque;
|
||||
|
||||
GFS2_I(inode)->i_no_addr = no_addr;
|
||||
inode->i_ino = no_addr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* gfs2_inode_lookup - Lookup an inode
|
||||
* @sb: The super block
|
||||
@@ -132,12 +117,11 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
|
||||
{
|
||||
struct inode *inode;
|
||||
struct gfs2_inode *ip;
|
||||
struct gfs2_glock *io_gl = NULL;
|
||||
struct gfs2_holder i_gh;
|
||||
int error;
|
||||
|
||||
gfs2_holder_mark_uninitialized(&i_gh);
|
||||
inode = gfs2_iget(sb, no_addr);
|
||||
inode = iget5_locked(sb, no_addr, iget_test, iget_set, &no_addr);
|
||||
if (!inode)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@@ -145,22 +129,16 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
|
||||
|
||||
if (inode->i_state & I_NEW) {
|
||||
struct gfs2_sbd *sdp = GFS2_SB(inode);
|
||||
struct gfs2_glock *io_gl;
|
||||
|
||||
error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl);
|
||||
if (unlikely(error))
|
||||
goto fail;
|
||||
flush_delayed_work(&ip->i_gl->gl_work);
|
||||
|
||||
error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
|
||||
if (unlikely(error))
|
||||
goto fail;
|
||||
if (blktype != GFS2_BLKST_UNLINKED)
|
||||
gfs2_cancel_delete_work(io_gl);
|
||||
|
||||
if (type == DT_UNKNOWN || blktype != GFS2_BLKST_FREE) {
|
||||
/*
|
||||
* The GL_SKIP flag indicates to skip reading the inode
|
||||
* block. We read the inode with gfs2_inode_refresh
|
||||
* block. We read the inode when instantiating it
|
||||
* after possibly checking the block type.
|
||||
*/
|
||||
error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE,
|
||||
@@ -181,24 +159,31 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
|
||||
}
|
||||
}
|
||||
|
||||
glock_set_object(ip->i_gl, ip);
|
||||
set_bit(GLF_INSTANTIATE_NEEDED, &ip->i_gl->gl_flags);
|
||||
error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh);
|
||||
|
||||
error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
|
||||
if (unlikely(error))
|
||||
goto fail;
|
||||
glock_set_object(ip->i_iopen_gh.gh_gl, ip);
|
||||
if (blktype != GFS2_BLKST_UNLINKED)
|
||||
gfs2_cancel_delete_work(io_gl);
|
||||
error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh);
|
||||
gfs2_glock_put(io_gl);
|
||||
io_gl = NULL;
|
||||
if (unlikely(error))
|
||||
goto fail;
|
||||
|
||||
/* Lowest possible timestamp; will be overwritten in gfs2_dinode_in. */
|
||||
inode->i_atime.tv_sec = 1LL << (8 * sizeof(inode->i_atime.tv_sec) - 1);
|
||||
inode->i_atime.tv_nsec = 0;
|
||||
|
||||
glock_set_object(ip->i_gl, ip);
|
||||
|
||||
if (type == DT_UNKNOWN) {
|
||||
/* Inode glock must be locked already */
|
||||
error = gfs2_instantiate(&i_gh);
|
||||
if (error)
|
||||
if (error) {
|
||||
glock_clear_object(ip->i_gl, ip);
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
ip->i_no_formal_ino = no_formal_ino;
|
||||
inode->i_mode = DT2IF(type);
|
||||
@@ -206,31 +191,23 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
|
||||
|
||||
if (gfs2_holder_initialized(&i_gh))
|
||||
gfs2_glock_dq_uninit(&i_gh);
|
||||
glock_set_object(ip->i_iopen_gh.gh_gl, ip);
|
||||
|
||||
gfs2_set_iop(inode);
|
||||
unlock_new_inode(inode);
|
||||
}
|
||||
|
||||
if (no_formal_ino && ip->i_no_formal_ino &&
|
||||
no_formal_ino != ip->i_no_formal_ino) {
|
||||
error = -ESTALE;
|
||||
if (inode->i_state & I_NEW)
|
||||
goto fail;
|
||||
iput(inode);
|
||||
return ERR_PTR(error);
|
||||
return ERR_PTR(-ESTALE);
|
||||
}
|
||||
|
||||
if (inode->i_state & I_NEW)
|
||||
unlock_new_inode(inode);
|
||||
|
||||
return inode;
|
||||
|
||||
fail:
|
||||
if (gfs2_holder_initialized(&ip->i_iopen_gh)) {
|
||||
glock_clear_object(ip->i_iopen_gh.gh_gl, ip);
|
||||
if (gfs2_holder_initialized(&ip->i_iopen_gh))
|
||||
gfs2_glock_dq_uninit(&ip->i_iopen_gh);
|
||||
}
|
||||
if (io_gl)
|
||||
gfs2_glock_put(io_gl);
|
||||
if (gfs2_holder_initialized(&i_gh))
|
||||
gfs2_glock_dq_uninit(&i_gh);
|
||||
iget_failed(inode);
|
||||
@@ -730,18 +707,19 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
|
||||
error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl);
|
||||
if (error)
|
||||
goto fail_free_inode;
|
||||
flush_delayed_work(&ip->i_gl->gl_work);
|
||||
|
||||
error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
|
||||
if (error)
|
||||
goto fail_free_inode;
|
||||
gfs2_cancel_delete_work(io_gl);
|
||||
|
||||
error = insert_inode_locked4(inode, ip->i_no_addr, iget_test, &ip->i_no_addr);
|
||||
BUG_ON(error);
|
||||
|
||||
error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1);
|
||||
if (error)
|
||||
goto fail_gunlock2;
|
||||
|
||||
glock_set_object(ip->i_gl, ip);
|
||||
error = gfs2_trans_begin(sdp, blocks, 0);
|
||||
if (error)
|
||||
goto fail_gunlock2;
|
||||
@@ -757,9 +735,9 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
|
||||
if (error)
|
||||
goto fail_gunlock2;
|
||||
|
||||
glock_set_object(ip->i_gl, ip);
|
||||
glock_set_object(io_gl, ip);
|
||||
gfs2_set_iop(inode);
|
||||
insert_inode_hash(inode);
|
||||
|
||||
free_vfs_inode = 0; /* After this point, the inode is no longer
|
||||
considered free. Any failures need to undo
|
||||
@@ -801,17 +779,17 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
|
||||
gfs2_glock_dq_uninit(ghs + 1);
|
||||
gfs2_glock_put(io_gl);
|
||||
gfs2_qa_put(dip);
|
||||
unlock_new_inode(inode);
|
||||
return error;
|
||||
|
||||
fail_gunlock3:
|
||||
glock_clear_object(ip->i_gl, ip);
|
||||
glock_clear_object(io_gl, ip);
|
||||
gfs2_glock_dq_uninit(&ip->i_iopen_gh);
|
||||
fail_gunlock2:
|
||||
glock_clear_object(io_gl, ip);
|
||||
gfs2_glock_put(io_gl);
|
||||
fail_free_inode:
|
||||
if (ip->i_gl) {
|
||||
glock_clear_object(ip->i_gl, ip);
|
||||
if (free_vfs_inode) /* else evict will do the put for us */
|
||||
gfs2_glock_put(ip->i_gl);
|
||||
}
|
||||
@@ -829,7 +807,10 @@ fail_gunlock:
|
||||
mark_inode_dirty(inode);
|
||||
set_bit(free_vfs_inode ? GIF_FREE_VFS_INODE : GIF_ALLOC_FAILED,
|
||||
&GFS2_I(inode)->i_flags);
|
||||
iput(inode);
|
||||
if (inode->i_state & I_NEW)
|
||||
iget_failed(inode);
|
||||
else
|
||||
iput(inode);
|
||||
}
|
||||
if (gfs2_holder_initialized(ghs + 1))
|
||||
gfs2_glock_dq_uninit(ghs + 1);
|
||||
|
||||
@@ -714,6 +714,13 @@ static bool io_wq_work_match_all(struct io_wq_work *work, void *data)
|
||||
|
||||
static inline bool io_should_retry_thread(long err)
|
||||
{
|
||||
/*
|
||||
* Prevent perpetual task_work retry, if the task (or its group) is
|
||||
* exiting.
|
||||
*/
|
||||
if (fatal_signal_pending(current))
|
||||
return false;
|
||||
|
||||
switch (err) {
|
||||
case -EAGAIN:
|
||||
case -ERESTARTSYS:
|
||||
|
||||
@@ -3122,7 +3122,6 @@ xfs_rename(
|
||||
* appropriately.
|
||||
*/
|
||||
if (flags & RENAME_WHITEOUT) {
|
||||
ASSERT(!(flags & (RENAME_NOREPLACE | RENAME_EXCHANGE)));
|
||||
error = xfs_rename_alloc_whiteout(mnt_userns, target_dp, &wip);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
Reference in New Issue
Block a user