Skip to content

Commit

Permalink
Merge branch 'master' of git://git.kernel.org/pub/scm/fs/xfs/xfs
Browse files Browse the repository at this point in the history
  • Loading branch information
Felix Blyakher committed Feb 9, 2009
2 parents d41d411 + 8e9b6e7 commit 9483c89
Show file tree
Hide file tree
Showing 14 changed files with 239 additions and 348 deletions.
106 changes: 44 additions & 62 deletions fs/xfs/linux-2.6/xfs_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,92 +78,74 @@ xfs_find_handle(
int hsize;
xfs_handle_t handle;
struct inode *inode;
struct file *file = NULL;
struct path path;
int error;
struct xfs_inode *ip;

memset((char *)&handle, 0, sizeof(handle));

switch (cmd) {
case XFS_IOC_PATH_TO_FSHANDLE:
case XFS_IOC_PATH_TO_HANDLE: {
struct path path;
int error = user_lpath((const char __user *)hreq->path, &path);
if (cmd == XFS_IOC_FD_TO_HANDLE) {
file = fget(hreq->fd);
if (!file)
return -EBADF;
inode = file->f_path.dentry->d_inode;
} else {
error = user_lpath((const char __user *)hreq->path, &path);
if (error)
return error;

ASSERT(path.dentry);
ASSERT(path.dentry->d_inode);
inode = igrab(path.dentry->d_inode);
path_put(&path);
break;
inode = path.dentry->d_inode;
}
ip = XFS_I(inode);

case XFS_IOC_FD_TO_HANDLE: {
struct file *file;

file = fget(hreq->fd);
if (!file)
return -EBADF;
/*
* We can only generate handles for inodes residing on a XFS filesystem,
* and only for regular files, directories or symbolic links.
*/
error = -EINVAL;
if (inode->i_sb->s_magic != XFS_SB_MAGIC)
goto out_put;

ASSERT(file->f_path.dentry);
ASSERT(file->f_path.dentry->d_inode);
inode = igrab(file->f_path.dentry->d_inode);
fput(file);
break;
}
error = -EBADF;
if (!S_ISREG(inode->i_mode) &&
!S_ISDIR(inode->i_mode) &&
!S_ISLNK(inode->i_mode))
goto out_put;

default:
ASSERT(0);
return -XFS_ERROR(EINVAL);
}

if (inode->i_sb->s_magic != XFS_SB_MAGIC) {
/* we're not in XFS anymore, Toto */
iput(inode);
return -XFS_ERROR(EINVAL);
}
memcpy(&handle.ha_fsid, ip->i_mount->m_fixedfsid, sizeof(xfs_fsid_t));

switch (inode->i_mode & S_IFMT) {
case S_IFREG:
case S_IFDIR:
case S_IFLNK:
break;
default:
iput(inode);
return -XFS_ERROR(EBADF);
}

/* now we can grab the fsid */
memcpy(&handle.ha_fsid, XFS_I(inode)->i_mount->m_fixedfsid,
sizeof(xfs_fsid_t));
hsize = sizeof(xfs_fsid_t);

if (cmd != XFS_IOC_PATH_TO_FSHANDLE) {
xfs_inode_t *ip = XFS_I(inode);
if (cmd == XFS_IOC_PATH_TO_FSHANDLE) {
/*
* This handle only contains an fsid, zero the rest.
*/
memset(&handle.ha_fid, 0, sizeof(handle.ha_fid));
hsize = sizeof(xfs_fsid_t);
} else {
int lock_mode;

/* need to get access to the xfs_inode to read the generation */
lock_mode = xfs_ilock_map_shared(ip);

/* fill in fid section of handle from inode */
handle.ha_fid.fid_len = sizeof(xfs_fid_t) -
sizeof(handle.ha_fid.fid_len);
handle.ha_fid.fid_pad = 0;
handle.ha_fid.fid_gen = ip->i_d.di_gen;
handle.ha_fid.fid_ino = ip->i_ino;

xfs_iunlock_map_shared(ip, lock_mode);

hsize = XFS_HSIZE(handle);
}

/* now copy our handle into the user buffer & write out the size */
error = -EFAULT;
if (copy_to_user(hreq->ohandle, &handle, hsize) ||
copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32))) {
iput(inode);
return -XFS_ERROR(EFAULT);
}
copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32)))
goto out_put;

iput(inode);
return 0;
error = 0;

out_put:
if (cmd == XFS_IOC_FD_TO_HANDLE)
fput(file);
else
path_put(&path);
return error;
}

/*
Expand Down
43 changes: 37 additions & 6 deletions fs/xfs/linux-2.6/xfs_super.c
Original file line number Diff line number Diff line change
Expand Up @@ -990,26 +990,57 @@ xfs_fs_write_inode(
int sync)
{
struct xfs_inode *ip = XFS_I(inode);
struct xfs_mount *mp = ip->i_mount;
int error = 0;
int flags = 0;

xfs_itrace_entry(ip);

if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO);

if (sync) {
error = xfs_wait_on_pages(ip, 0, -1);
if (error)
goto out_error;
flags |= FLUSH_SYNC;
goto out;
}

/*
* Bypass inodes which have already been cleaned by
* the inode flush clustering code inside xfs_iflush
*/
if (xfs_inode_clean(ip))
goto out;

/*
* We make this non-blocking if the inode is contended, return
* EAGAIN to indicate to the caller that they did not succeed.
* This prevents the flush path from blocking on inodes inside
* another operation right now, they get caught later by xfs_sync.
*/
if (sync) {
xfs_ilock(ip, XFS_ILOCK_SHARED);
xfs_iflock(ip);

error = xfs_iflush(ip, XFS_IFLUSH_SYNC);
} else {
error = EAGAIN;
if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED))
goto out;
if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip))
goto out_unlock;

error = xfs_iflush(ip, XFS_IFLUSH_ASYNC_NOBLOCK);
}
error = xfs_inode_flush(ip, flags);

out_error:
out_unlock:
xfs_iunlock(ip, XFS_ILOCK_SHARED);
out:
/*
* if we failed to write out the inode then mark
* it dirty again so we'll try again later.
*/
if (error)
xfs_mark_inode_dirty_sync(ip);

return -error;
}

Expand Down
5 changes: 0 additions & 5 deletions fs/xfs/linux-2.6/xfs_vnode.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,6 @@ struct attrlist_cursor_kern;
#define IO_ISDIRECT 0x00004 /* bypass page cache */
#define IO_INVIS 0x00020 /* don't update inode timestamps */

/*
* Flags for xfs_inode_flush
*/
#define FLUSH_SYNC 1 /* wait for flush to complete */

/*
* Flush/Invalidate options for vop_toss/flush/flushinval_pages.
*/
Expand Down
Loading

0 comments on commit 9483c89

Please sign in to comment.