Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a55f2d86 authored by Martin Brandenburg's avatar Martin Brandenburg Committed by Mike Marshall
Browse files

orangefs: stop setting atime on inode dirty



The previous code path was to mark the inode dirty, let
orangefs_inode_dirty set a flag in our private inode, then later during
inode release call orangefs_flush_inode which notices the flag and
writes the atime out.

The code path worked almost identically for mtime, ctime, and mode
except that those flags are set explicitly and not as side effects of
dirty.

Now orangefs_flush_inode is removed.  Marking an inode dirty does not
imply an atime update.  Any place where flags were set before is now
an explicit call to orangefs_inode_setattr.  Since OrangeFS does not
utilize inode writeback, the attribute change should be written out
immediately.

Fixes generic/120.

In namei.c, there are several places where the directory mtime and ctime
are set, but only the mtime is sent to the server.  These don't seem
right, but I've left them as is for now.

Signed-off-by: default avatarMartin Brandenburg <martin@omnibond.com>
Signed-off-by: default avatarMike Marshall <hubcap@omnibond.com>
parent 296200d3
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -155,13 +155,11 @@ int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type)

int orangefs_init_acl(struct inode *inode, struct inode *dir)
{
	struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
	struct posix_acl *default_acl, *acl;
	umode_t mode = inode->i_mode;
	struct iattr iattr;
	int error = 0;

	ClearModeFlag(orangefs_inode);

	error = posix_acl_create(dir, &mode, &default_acl, &acl);
	if (error)
		return error;
@@ -180,9 +178,11 @@ int orangefs_init_acl(struct inode *inode, struct inode *dir)

	/* If mode of the inode was changed, then do a forcible ->setattr */
	if (mode != inode->i_mode) {
		SetModeFlag(orangefs_inode);
		memset(&iattr, 0, sizeof iattr);
		inode->i_mode = mode;
		orangefs_flush_inode(inode);
		iattr.ia_mode = mode;
		iattr.ia_valid |= ATTR_MODE;
		orangefs_inode_setattr(inode, &iattr);
	}

	return error;
+0 −1
Original line number Diff line number Diff line
@@ -386,7 +386,6 @@ static int orangefs_dir_release(struct inode *inode, struct file *file)
{
	struct orangefs_dir *od = file->private_data;
	struct orangefs_dir_part *part = od->part;
	orangefs_flush_inode(inode);
	while (part) {
		struct orangefs_dir_part *next = part->next;
		vfree(part);
+9 −7
Original line number Diff line number Diff line
@@ -383,9 +383,15 @@ static ssize_t do_readv_writev(enum ORANGEFS_io_type type, struct file *file,
		if (type == ORANGEFS_IO_READ) {
			file_accessed(file);
		} else {
			SetMtimeFlag(orangefs_inode);
			inode->i_mtime = current_time(inode);
			mark_inode_dirty_sync(inode);
			file_update_time(file);
			/*
			 * Must invalidate to ensure write loop doesn't
			 * prevent kernel from reading updated
			 * attribute.  Size probably changed because of
			 * the write, and other clients could update
			 * any other attribute.
			 */
			orangefs_inode->getattr_time = jiffies - 1;
		}
	}

@@ -615,8 +621,6 @@ static int orangefs_file_release(struct inode *inode, struct file *file)
		     "orangefs_file_release: called on %pD\n",
		     file);

	orangefs_flush_inode(inode);

	/*
	 * remove all associated inode pages from the page cache and
	 * readahead cache (if any); this forces an expensive refresh of
@@ -666,8 +670,6 @@ static int orangefs_fsync(struct file *file,
		     ret);

	op_release(new_op);

	orangefs_flush_inode(file_inode(file));
	return ret;
}

+17 −0
Original line number Diff line number Diff line
@@ -290,6 +290,22 @@ int orangefs_permission(struct inode *inode, int mask)
	return generic_permission(inode, mask);
}

int orangefs_update_time(struct inode *inode, struct timespec *time, int flags)
{
	struct iattr iattr;
	gossip_debug(GOSSIP_INODE_DEBUG, "orangefs_update_time: %pU\n",
	    get_khandle_from_ino(inode));
	generic_update_time(inode, time, flags);
	memset(&iattr, 0, sizeof iattr);
        if (flags & S_ATIME)
		iattr.ia_valid |= ATTR_ATIME;
	if (flags & S_CTIME)
		iattr.ia_valid |= ATTR_CTIME;
	if (flags & S_MTIME)
		iattr.ia_valid |= ATTR_MTIME;
	return orangefs_inode_setattr(inode, &iattr);
}

/* ORANGEDS2 implementation of VFS inode operations for files */
const struct inode_operations orangefs_file_inode_operations = {
	.get_acl = orangefs_get_acl,
@@ -298,6 +314,7 @@ const struct inode_operations orangefs_file_inode_operations = {
	.getattr = orangefs_getattr,
	.listxattr = orangefs_listxattr,
	.permission = orangefs_permission,
	.update_time = orangefs_update_time,
};

static int orangefs_init_iops(struct inode *inode)
+17 −4
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ static int orangefs_create(struct inode *dir,
	struct orangefs_inode_s *parent = ORANGEFS_I(dir);
	struct orangefs_kernel_op_s *new_op;
	struct inode *inode;
	struct iattr iattr;
	int ret;

	gossip_debug(GOSSIP_NAME_DEBUG, "%s: %pd\n",
@@ -82,8 +83,10 @@ static int orangefs_create(struct inode *dir,
		     __func__,
		     dentry);

	SetMtimeFlag(parent);
	dir->i_mtime = dir->i_ctime = current_time(dir);
	memset(&iattr, 0, sizeof iattr);
	iattr.ia_valid |= ATTR_MTIME;
	orangefs_inode_setattr(dir, &iattr);
	mark_inode_dirty_sync(dir);
	ret = 0;
out:
@@ -221,6 +224,7 @@ static int orangefs_unlink(struct inode *dir, struct dentry *dentry)
	struct inode *inode = dentry->d_inode;
	struct orangefs_inode_s *parent = ORANGEFS_I(dir);
	struct orangefs_kernel_op_s *new_op;
	struct iattr iattr;
	int ret;

	gossip_debug(GOSSIP_NAME_DEBUG,
@@ -253,8 +257,10 @@ static int orangefs_unlink(struct inode *dir, struct dentry *dentry)
	if (!ret) {
		drop_nlink(inode);

		SetMtimeFlag(parent);
		dir->i_mtime = dir->i_ctime = current_time(dir);
		memset(&iattr, 0, sizeof iattr);
		iattr.ia_valid |= ATTR_MTIME;
		orangefs_inode_setattr(dir, &iattr);
		mark_inode_dirty_sync(dir);
	}
	return ret;
@@ -267,6 +273,7 @@ static int orangefs_symlink(struct inode *dir,
	struct orangefs_inode_s *parent = ORANGEFS_I(dir);
	struct orangefs_kernel_op_s *new_op;
	struct inode *inode;
	struct iattr iattr;
	int mode = 755;
	int ret;

@@ -331,8 +338,10 @@ static int orangefs_symlink(struct inode *dir,
		     get_khandle_from_ino(inode),
		     dentry);

	SetMtimeFlag(parent);
	dir->i_mtime = dir->i_ctime = current_time(dir);
	memset(&iattr, 0, sizeof iattr);
	iattr.ia_valid |= ATTR_MTIME;
	orangefs_inode_setattr(dir, &iattr);
	mark_inode_dirty_sync(dir);
	ret = 0;
out:
@@ -345,6 +354,7 @@ static int orangefs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
	struct orangefs_inode_s *parent = ORANGEFS_I(dir);
	struct orangefs_kernel_op_s *new_op;
	struct inode *inode;
	struct iattr iattr;
	int ret;

	new_op = op_alloc(ORANGEFS_VFS_OP_MKDIR);
@@ -400,8 +410,10 @@ static int orangefs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
	 * NOTE: we have no good way to keep nlink consistent for directories
	 * across clients; keep constant at 1.
	 */
	SetMtimeFlag(parent);
	dir->i_mtime = dir->i_ctime = current_time(dir);
	memset(&iattr, 0, sizeof iattr);
	iattr.ia_valid |= ATTR_MTIME;
	orangefs_inode_setattr(dir, &iattr);
	mark_inode_dirty_sync(dir);
out:
	op_release(new_op);
@@ -470,4 +482,5 @@ const struct inode_operations orangefs_dir_inode_operations = {
	.getattr = orangefs_getattr,
	.listxattr = orangefs_listxattr,
	.permission = orangefs_permission,
	.update_time = orangefs_update_time,
};
Loading