scoutfs: add inode locking flags to callers

Now that we have the inode refreshing flags let's add them to the
callers that want to have a current inode after they have their lock.
Callers locking newly created items use the new inode flag to reset the
refresh gen.

A few inode tests are moved down to after locking so that it can test
the current refreshed inode.

Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
Zach Brown
2017-08-23 16:07:16 -07:00
parent a08530a24e
commit ceccc56c8f
2 changed files with 47 additions and 31 deletions

View File

@@ -500,7 +500,8 @@ static int scoutfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
if (ret)
return ret;
ret = scoutfs_lock_inode(sb, DLM_LOCK_EX, 0, dir, &dir_lock);
ret = scoutfs_lock_inode(sb, DLM_LOCK_EX, SCOUTFS_LKF_REFRESH_INODE,
dir, &dir_lock);
if (ret)
return ret;
@@ -571,17 +572,22 @@ static int scoutfs_link(struct dentry *old_dentry,
DECLARE_ITEM_COUNT(cnt);
int ret;
if (inode->i_nlink >= SCOUTFS_LINK_MAX)
return -EMLINK;
ret = scoutfs_lock_inode(sb, DLM_LOCK_EX, 0, dir, &dir_lock);
ret = scoutfs_lock_inode(sb, DLM_LOCK_EX, SCOUTFS_LKF_REFRESH_INODE,
dir, &dir_lock);
if (ret)
return ret;
ret = scoutfs_lock_inode(sb, DLM_LOCK_EX, 0, inode, &inode_lock);
ret = scoutfs_lock_inode(sb, DLM_LOCK_EX, SCOUTFS_LKF_REFRESH_INODE,
inode, &inode_lock);
if (ret)
goto out_unlock;
if (inode->i_nlink >= SCOUTFS_LINK_MAX) {
ret = -EMLINK;
goto out_unlock;
}
ret = alloc_dentry_info(dentry);
if (ret)
goto out_unlock;
@@ -631,17 +637,22 @@ static int scoutfs_unlink(struct inode *dir, struct dentry *dentry)
struct scoutfs_lock *inode_lock = NULL;
int ret = 0;
if (S_ISDIR(inode->i_mode) && i_size_read(inode))
return -ENOTEMPTY;
ret = scoutfs_lock_inode(sb, DLM_LOCK_EX, 0, dir, &dir_lock);
ret = scoutfs_lock_inode(sb, DLM_LOCK_EX, SCOUTFS_LKF_REFRESH_INODE,
dir, &dir_lock);
if (ret)
return ret;
ret = scoutfs_lock_inode(sb, DLM_LOCK_EX, 0, inode, &inode_lock);
ret = scoutfs_lock_inode(sb, DLM_LOCK_EX, SCOUTFS_LKF_REFRESH_INODE,
inode, &inode_lock);
if (ret)
goto out;
if (S_ISDIR(inode->i_mode) && i_size_read(inode)) {
ret = -ENOTEMPTY;
goto out;
}
keys[0] = alloc_dirent_key(sb, dir, dentry);
if (!keys[0]) {
ret = -ENOMEM;
@@ -792,25 +803,32 @@ static void *scoutfs_follow_link(struct dentry *dentry, struct nameidata *nd)
struct inode *inode = dentry->d_inode;
struct super_block *sb = inode->i_sb;
struct scoutfs_lock *inode_lock = NULL;
loff_t size = i_size_read(inode);
char *path;
char *path = NULL;
loff_t size;
int ret;
/* XXX corruption */
if (size == 0 || size > SCOUTFS_SYMLINK_MAX_SIZE)
return ERR_PTR(-EIO);
/* unlikely, but possible I suppose */
if (size > PATH_MAX)
return ERR_PTR(-ENAMETOOLONG);
ret = scoutfs_lock_inode(sb, DLM_LOCK_PR, 0, inode, &inode_lock);
ret = scoutfs_lock_inode(sb, DLM_LOCK_PR, SCOUTFS_LKF_REFRESH_INODE,
inode, &inode_lock);
if (ret)
return ERR_PTR(ret);
size = i_size_read(inode);
/* XXX corruption */
if (size == 0 || size > SCOUTFS_SYMLINK_MAX_SIZE) {
ret = -EIO;
goto out;
}
/* unlikely, but possible I suppose */
if (size > PATH_MAX) {
ret = -ENAMETOOLONG;
goto out;
}
path = kmalloc(size, GFP_NOFS);
if (!path) {
path = ERR_PTR(-ENOMEM);
ret = -ENOMEM;
goto out;
}
@@ -821,13 +839,13 @@ static void *scoutfs_follow_link(struct dentry *dentry, struct nameidata *nd)
if (ret == -ENOENT || (ret == 0 && path[size - 1]))
ret = -EIO;
out:
if (ret < 0) {
kfree(path);
path = ERR_PTR(ret);
} else {
nd_set_link(nd, path);
}
out:
scoutfs_unlock(sb, inode_lock, DLM_LOCK_PR);
return path;
}
@@ -872,7 +890,8 @@ static int scoutfs_symlink(struct inode *dir, struct dentry *dentry,
if (ret)
return ret;
ret = scoutfs_lock_inode(sb, DLM_LOCK_EX, 0, dir, &dir_lock);
ret = scoutfs_lock_inode(sb, DLM_LOCK_EX, SCOUTFS_LKF_REFRESH_INODE,
dir, &dir_lock);
if (ret)
return ret;

View File

@@ -306,15 +306,12 @@ static int scoutfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct scoutfs_lock *lock = NULL;
int ret;
ret = scoutfs_lock_inode(sb, DLM_LOCK_PR, 0, inode, &lock);
if (ret)
return ret;
ret = scoutfs_inode_refresh(inode, lock, 0);
if (ret == 0)
ret = scoutfs_lock_inode(sb, DLM_LOCK_PR, SCOUTFS_LKF_REFRESH_INODE,
inode, &lock);
if (ret == 0) {
generic_fillattr(inode, stat);
scoutfs_unlock(sb, lock, DLM_LOCK_PR);
scoutfs_unlock(sb, lock, DLM_LOCK_PR);
}
return ret;
}