Skip to content

Commit 4fae90d

Browse files
committed
Merge patch series "include/linux/fs.h: add inode_lock_killable()"
Try and make a few filesystem operations killable on the VFS inode->i_mutex level. * patches from https://lore.kernel.org/[email protected]: fs/read_write: make default_llseek() killable fs/open: make do_truncate() killable fs/open: make chmod_common() and chown_common() killable include/linux/fs.h: add inode_lock_killable() Link: https://lore.kernel.org/[email protected] Signed-off-by: Christian Brauner <[email protected]>
2 parents e0410e9 + 2e1a8fb commit 4fae90d

File tree

3 files changed

+24
-4
lines changed

3 files changed

+24
-4
lines changed

fs/open.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@ int do_truncate(struct mnt_idmap *idmap, struct dentry *dentry,
6060
if (ret)
6161
newattrs.ia_valid |= ret | ATTR_FORCE;
6262

63-
inode_lock(dentry->d_inode);
63+
ret = inode_lock_killable(dentry->d_inode);
64+
if (ret)
65+
return ret;
66+
6467
/* Note any delegations or leases have already been broken: */
6568
ret = notify_change(idmap, dentry, &newattrs, NULL);
6669
inode_unlock(dentry->d_inode);
@@ -635,7 +638,9 @@ int chmod_common(const struct path *path, umode_t mode)
635638
if (error)
636639
return error;
637640
retry_deleg:
638-
inode_lock(inode);
641+
error = inode_lock_killable(inode);
642+
if (error)
643+
goto out_mnt_unlock;
639644
error = security_path_chmod(path, mode);
640645
if (error)
641646
goto out_unlock;
@@ -650,6 +655,7 @@ int chmod_common(const struct path *path, umode_t mode)
650655
if (!error)
651656
goto retry_deleg;
652657
}
658+
out_mnt_unlock:
653659
mnt_drop_write(path->mnt);
654660
return error;
655661
}
@@ -769,7 +775,9 @@ int chown_common(const struct path *path, uid_t user, gid_t group)
769775
return -EINVAL;
770776
if ((group != (gid_t)-1) && !setattr_vfsgid(&newattrs, gid))
771777
return -EINVAL;
772-
inode_lock(inode);
778+
error = inode_lock_killable(inode);
779+
if (error)
780+
return error;
773781
if (!S_ISDIR(inode->i_mode))
774782
newattrs.ia_valid |= ATTR_KILL_SUID | ATTR_KILL_PRIV |
775783
setattr_should_drop_sgid(idmap, inode);

fs/read_write.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,9 @@ loff_t default_llseek(struct file *file, loff_t offset, int whence)
332332
struct inode *inode = file_inode(file);
333333
loff_t retval;
334334

335-
inode_lock(inode);
335+
retval = inode_lock_killable(inode);
336+
if (retval)
337+
return retval;
336338
switch (whence) {
337339
case SEEK_END:
338340
offset += i_size_read(inode);

include/linux/fs.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,11 @@ static inline void inode_lock(struct inode *inode)
867867
down_write(&inode->i_rwsem);
868868
}
869869

870+
static inline __must_check int inode_lock_killable(struct inode *inode)
871+
{
872+
return down_write_killable(&inode->i_rwsem);
873+
}
874+
870875
static inline void inode_unlock(struct inode *inode)
871876
{
872877
up_write(&inode->i_rwsem);
@@ -877,6 +882,11 @@ static inline void inode_lock_shared(struct inode *inode)
877882
down_read(&inode->i_rwsem);
878883
}
879884

885+
static inline __must_check int inode_lock_shared_killable(struct inode *inode)
886+
{
887+
return down_read_killable(&inode->i_rwsem);
888+
}
889+
880890
static inline void inode_unlock_shared(struct inode *inode)
881891
{
882892
up_read(&inode->i_rwsem);

0 commit comments

Comments
 (0)