*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/fs.h>
#include <linux/ctype.h>
#include <linux/quotaops.h>
+#include <linux/vs_tag.h>
#include "jfs_incore.h"
#include "jfs_superblock.h"
#include "jfs_inode.h"
#include "jfs_acl.h"
#include "jfs_debug.h"
-extern struct inode_operations jfs_file_inode_operations;
-extern struct inode_operations jfs_symlink_inode_operations;
-extern struct file_operations jfs_file_operations;
-extern struct address_space_operations jfs_aops;
-
-extern int jfs_fsync(struct file *, struct dentry *, int);
-extern void jfs_truncate_nolock(struct inode *, loff_t);
-extern int jfs_init_acl(struct inode *, struct inode *);
-
/*
* forward references
*/
-struct inode_operations jfs_dir_inode_operations;
-struct file_operations jfs_dir_operations;
struct dentry_operations jfs_ci_dentry_operations;
static s64 commitZeroLink(tid_t, struct inode *);
+/*
+ * NAME: free_ea_wmap(inode)
+ *
+ * FUNCTION: free uncommitted extended attributes from working map
+ *
+ */
+static inline void free_ea_wmap(struct inode *inode)
+{
+ dxd_t *ea = &JFS_IP(inode)->ea;
+
+ if (ea->flag & DXD_EXTENT) {
+ /* free EA pages from cache */
+ invalidate_dxd_metapages(inode, *ea);
+ dbFree(inode, addressDXD(ea), lengthDXD(ea));
+ }
+ ea->flag = 0;
+}
+
/*
* NAME: jfs_create(dip, dentry, mode)
*
* FUNCTION: create a regular file in the parent directory <dip>
* with name = <from dentry> and mode = <mode>
*
- * PARAMETER: dip - parent directory vnode
+ * PARAMETER: dip - parent directory vnode
* dentry - dentry of new file
* mode - create mode (rwxrwxrwx).
* nd- nd struct
* begin the transaction before we search the directory.
*/
ip = ialloc(dip, mode);
- if (ip == NULL) {
- rc = -ENOSPC;
+ if (IS_ERR(ip)) {
+ rc = PTR_ERR(ip);
goto out2;
}
tid = txBegin(dip->i_sb, 0);
- down(&JFS_IP(dip)->commit_sem);
- down(&JFS_IP(ip)->commit_sem);
+ mutex_lock(&JFS_IP(dip)->commit_mutex);
+ mutex_lock(&JFS_IP(ip)->commit_mutex);
+
+ rc = jfs_init_acl(tid, ip, dip);
+ if (rc)
+ goto out3;
+
+ rc = jfs_init_security(tid, ip, dip);
+ if (rc) {
+ txAbort(tid, 0);
+ goto out3;
+ }
if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) {
jfs_err("jfs_create: dtSearch returned %d", rc);
+ txAbort(tid, 0);
goto out3;
}
out3:
txEnd(tid);
- up(&JFS_IP(dip)->commit_sem);
- up(&JFS_IP(ip)->commit_sem);
+ mutex_unlock(&JFS_IP(ip)->commit_mutex);
+ mutex_unlock(&JFS_IP(dip)->commit_mutex);
if (rc) {
+ free_ea_wmap(ip);
ip->i_nlink = 0;
iput(ip);
} else
out2:
free_UCSname(&dname);
-#ifdef CONFIG_JFS_POSIX_ACL
- if (rc == 0)
- jfs_init_acl(ip, dip);
-#endif
-
out1:
jfs_info("jfs_create: rc:%d", rc);
* FUNCTION: create a child directory in the parent directory <dip>
* with name = <from dentry> and mode = <mode>
*
- * PARAMETER: dip - parent directory vnode
+ * PARAMETER: dip - parent directory vnode
* dentry - dentry of child directory
* mode - create mode (rwxrwxrwx).
*
* begin the transaction before we search the directory.
*/
ip = ialloc(dip, S_IFDIR | mode);
- if (ip == NULL) {
- rc = -ENOSPC;
+ if (IS_ERR(ip)) {
+ rc = PTR_ERR(ip);
goto out2;
}
tid = txBegin(dip->i_sb, 0);
- down(&JFS_IP(dip)->commit_sem);
- down(&JFS_IP(ip)->commit_sem);
+ mutex_lock(&JFS_IP(dip)->commit_mutex);
+ mutex_lock(&JFS_IP(ip)->commit_mutex);
+
+ rc = jfs_init_acl(tid, ip, dip);
+ if (rc)
+ goto out3;
+
+ rc = jfs_init_security(tid, ip, dip);
+ if (rc) {
+ txAbort(tid, 0);
+ goto out3;
+ }
if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) {
jfs_err("jfs_mkdir: dtSearch returned %d", rc);
+ txAbort(tid, 0);
goto out3;
}
ip->i_nlink = 2; /* for '.' */
ip->i_op = &jfs_dir_inode_operations;
ip->i_fop = &jfs_dir_operations;
- ip->i_mapping->a_ops = &jfs_aops;
- mapping_set_gfp_mask(ip->i_mapping, GFP_NOFS);
insert_inode_hash(ip);
mark_inode_dirty(ip);
/* update parent directory inode */
- dip->i_nlink++; /* for '..' from child directory */
+ inc_nlink(dip); /* for '..' from child directory */
dip->i_ctime = dip->i_mtime = CURRENT_TIME;
mark_inode_dirty(dip);
out3:
txEnd(tid);
- up(&JFS_IP(dip)->commit_sem);
- up(&JFS_IP(ip)->commit_sem);
+ mutex_unlock(&JFS_IP(ip)->commit_mutex);
+ mutex_unlock(&JFS_IP(dip)->commit_mutex);
if (rc) {
+ free_ea_wmap(ip);
ip->i_nlink = 0;
iput(ip);
} else
out2:
free_UCSname(&dname);
-#ifdef CONFIG_JFS_POSIX_ACL
- if (rc == 0)
- jfs_init_acl(ip, dip);
-#endif
out1:
*
* FUNCTION: remove a link to child directory
*
- * PARAMETER: dip - parent inode
+ * PARAMETER: dip - parent inode
* dentry - child directory dentry
*
* RETURN: -EINVAL - if name is . or ..
* errors from subroutines
*
* note:
- * if other threads have the directory open when the last link
- * is removed, the "." and ".." entries, if present, are removed before
- * rmdir() returns and no new entries may be created in the directory,
- * but the directory is not removed until the last reference to
+ * if other threads have the directory open when the last link
+ * is removed, the "." and ".." entries, if present, are removed before
+ * rmdir() returns and no new entries may be created in the directory,
+ * but the directory is not removed until the last reference to
* the directory is released (cf.unlink() of regular file).
*/
static int jfs_rmdir(struct inode *dip, struct dentry *dentry)
tid = txBegin(dip->i_sb, 0);
- down(&JFS_IP(dip)->commit_sem);
- down(&JFS_IP(ip)->commit_sem);
+ mutex_lock(&JFS_IP(dip)->commit_mutex);
+ mutex_lock(&JFS_IP(ip)->commit_mutex);
iplist[0] = dip;
iplist[1] = ip;
if (rc == -EIO)
txAbort(tid, 1);
txEnd(tid);
- up(&JFS_IP(dip)->commit_sem);
- up(&JFS_IP(ip)->commit_sem);
+ mutex_unlock(&JFS_IP(ip)->commit_mutex);
+ mutex_unlock(&JFS_IP(dip)->commit_mutex);
goto out2;
}
/* update parent directory's link count corresponding
* to ".." entry of the target directory deleted
*/
- dip->i_nlink--;
dip->i_ctime = dip->i_mtime = CURRENT_TIME;
- mark_inode_dirty(dip);
+ inode_dec_link_count(dip);
/*
* OS/2 could have created EA and/or ACL
JFS_IP(ip)->acl.flag = 0;
/* mark the target directory as deleted */
- ip->i_nlink = 0;
+ clear_nlink(ip);
mark_inode_dirty(ip);
rc = txCommit(tid, 2, &iplist[0], 0);
txEnd(tid);
- up(&JFS_IP(dip)->commit_sem);
- up(&JFS_IP(ip)->commit_sem);
+ mutex_unlock(&JFS_IP(ip)->commit_mutex);
+ mutex_unlock(&JFS_IP(dip)->commit_mutex);
/*
* Truncating the directory index table is not guaranteed. It
/*
* NAME: jfs_unlink(dip, dentry)
*
- * FUNCTION: remove a link to object <vp> named by <name>
+ * FUNCTION: remove a link to object <vp> named by <name>
* from parent directory <dvp>
*
- * PARAMETER: dip - inode of parent directory
- * dentry - dentry of object to be removed
+ * PARAMETER: dip - inode of parent directory
+ * dentry - dentry of object to be removed
*
* RETURN: errors from subroutines
*
tid = txBegin(dip->i_sb, 0);
- down(&JFS_IP(dip)->commit_sem);
- down(&JFS_IP(ip)->commit_sem);
+ mutex_lock(&JFS_IP(dip)->commit_mutex);
+ mutex_lock(&JFS_IP(ip)->commit_mutex);
iplist[0] = dip;
iplist[1] = ip;
if (rc == -EIO)
txAbort(tid, 1); /* Marks FS Dirty */
txEnd(tid);
- up(&JFS_IP(dip)->commit_sem);
- up(&JFS_IP(ip)->commit_sem);
+ mutex_unlock(&JFS_IP(ip)->commit_mutex);
+ mutex_unlock(&JFS_IP(dip)->commit_mutex);
IWRITE_UNLOCK(ip);
goto out1;
}
mark_inode_dirty(dip);
/* update target's inode */
- ip->i_nlink--;
- mark_inode_dirty(ip);
+ inode_dec_link_count(ip);
/*
* commit zero link count object
if ((new_size = commitZeroLink(tid, ip)) < 0) {
txAbort(tid, 1); /* Marks FS Dirty */
txEnd(tid);
- up(&JFS_IP(dip)->commit_sem);
- up(&JFS_IP(ip)->commit_sem);
+ mutex_unlock(&JFS_IP(ip)->commit_mutex);
+ mutex_unlock(&JFS_IP(dip)->commit_mutex);
IWRITE_UNLOCK(ip);
rc = new_size;
goto out1;
txEnd(tid);
- up(&JFS_IP(dip)->commit_sem);
- up(&JFS_IP(ip)->commit_sem);
-
+ mutex_unlock(&JFS_IP(ip)->commit_mutex);
+ mutex_unlock(&JFS_IP(dip)->commit_mutex);
while (new_size && (rc == 0)) {
tid = txBegin(dip->i_sb, 0);
- down(&JFS_IP(ip)->commit_sem);
+ mutex_lock(&JFS_IP(ip)->commit_mutex);
new_size = xtTruncate_pmap(tid, ip, new_size);
if (new_size < 0) {
txAbort(tid, 1); /* Marks FS Dirty */
} else
rc = txCommit(tid, 2, &iplist[0], COMMIT_SYNC);
txEnd(tid);
- up(&JFS_IP(ip)->commit_sem);
+ mutex_unlock(&JFS_IP(ip)->commit_mutex);
}
if (ip->i_nlink == 0)
*
* FUNCTION: for non-directory, called by jfs_remove(),
* truncate a regular file, directory or symbolic
- * link to zero length. return 0 if type is not
+ * link to zero length. return 0 if type is not
* one of these.
*
* if the file is currently associated with a VM segment
* map by ctrunc1.
* if there is no VM segment on entry, the resources are
* freed in both work and permanent map.
- * (? for temporary file - memory object is cached even
+ * (? for temporary file - memory object is cached even
* after no reference:
* reference count > 0 - )
*
/*
* free xtree/data (truncate to zero length):
- * free xtree/data pages from cache if COMMIT_PWMAP,
+ * free xtree/data pages from cache if COMMIT_PWMAP,
* free xtree/data blocks from persistent block map, and
* free xtree/data blocks from working block map if COMMIT_PWMAP;
*/
/*
- * NAME: freeZeroLink()
+ * NAME: jfs_free_zero_link()
*
* FUNCTION: for non-directory, called by iClose(),
- * free resources of a file from cache and WORKING map
+ * free resources of a file from cache and WORKING map
* for a file previously committed with zero link count
* while associated with a pager object,
*
* PARAMETER: ip - pointer to inode of file.
- *
- * RETURN: 0 -ok
*/
-int freeZeroLink(struct inode *ip)
+void jfs_free_zero_link(struct inode *ip)
{
- int rc = 0;
int type;
- jfs_info("freeZeroLink: ip = 0x%p", ip);
+ jfs_info("jfs_free_zero_link: ip = 0x%p", ip);
/* return if not reg or symbolic link or if size is
* already ok.
case S_IFLNK:
/* if its contained in inode nothing to do */
if (ip->i_size < IDATASIZE)
- return 0;
+ return;
break;
default:
- return 0;
+ return;
}
/*
* free xtree/data blocks from working block map;
*/
if (ip->i_size)
- rc = xtTruncate(0, ip, 0, COMMIT_WMAP);
-
- return rc;
+ xtTruncate(0, ip, 0, COMMIT_WMAP);
}
/*
* FUNCTION: create a link to <vp> by the name = <name>
* in the parent directory <dvp>
*
- * PARAMETER: vp - target object
+ * PARAMETER: vp - target object
* dvp - parent directory of new link
* name - name of new link to target object
* crp - credential
tid = txBegin(ip->i_sb, 0);
- down(&JFS_IP(dir)->commit_sem);
- down(&JFS_IP(ip)->commit_sem);
+ mutex_lock(&JFS_IP(dir)->commit_mutex);
+ mutex_lock(&JFS_IP(ip)->commit_mutex);
/*
* scan parent directory for entry/freespace
goto free_dname;
/* update object inode */
- ip->i_nlink++; /* for new link */
+ inc_nlink(ip); /* for new link */
ip->i_ctime = CURRENT_TIME;
+ dir->i_ctime = dir->i_mtime = CURRENT_TIME;
mark_inode_dirty(dir);
atomic_inc(&ip->i_count);
rc = txCommit(tid, 2, &iplist[0], 0);
if (rc) {
- ip->i_nlink--;
+ ip->i_nlink--; /* never instantiated */
iput(ip);
} else
d_instantiate(dentry, ip);
out:
txEnd(tid);
- up(&JFS_IP(dir)->commit_sem);
- up(&JFS_IP(ip)->commit_sem);
+ mutex_unlock(&JFS_IP(ip)->commit_mutex);
+ mutex_unlock(&JFS_IP(dir)->commit_mutex);
jfs_info("jfs_link: rc:%d", rc);
return rc;
* in directory <dip>
*
* PARAMETER: dip - parent directory vnode
- * dentry - dentry of symbolic link
- * name - the path name of the existing object
+ * dentry - dentry of symbolic link
+ * name - the path name of the existing object
* that will be the source of the link
*
* RETURN: errors from subroutines
* (iAlloc() returns new, locked inode)
*/
ip = ialloc(dip, S_IFLNK | 0777);
- if (ip == NULL) {
- rc = -ENOSPC;
+ if (IS_ERR(ip)) {
+ rc = PTR_ERR(ip);
goto out2;
}
tid = txBegin(dip->i_sb, 0);
- down(&JFS_IP(dip)->commit_sem);
- down(&JFS_IP(ip)->commit_sem);
+ mutex_lock(&JFS_IP(dip)->commit_mutex);
+ mutex_lock(&JFS_IP(ip)->commit_mutex);
+
+ rc = jfs_init_security(tid, ip, dip);
+ if (rc)
+ goto out3;
tblk = tid_to_tblock(tid);
tblk->xflag |= COMMIT_CREATE;
tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
/* fix symlink access permission
- * (dir_create() ANDs in the u.u_cmask,
+ * (dir_create() ANDs in the u.u_cmask,
* but symlinks really need to be 777 access)
*/
ip->i_mode |= 0777;
ip->i_mapping->a_ops = &jfs_aops;
/*
- * even though the data of symlink object (source
+ * even though the data of symlink object (source
* path name) is treated as non-journaled user data,
* it is read/written thru buffer cache for performance.
*/
xlen = xsize >> JFS_SBI(sb)->l2bsize;
if ((rc = xtInsert(tid, ip, 0, 0, xlen, &xaddr, 0))) {
txAbort(tid, 0);
- rc = -ENOSPC;
goto out3;
}
extent = xaddr;
insert_inode_hash(ip);
mark_inode_dirty(ip);
+ dip->i_ctime = dip->i_mtime = CURRENT_TIME;
+ mark_inode_dirty(dip);
/*
* commit update of parent directory and link object
*/
out3:
txEnd(tid);
- up(&JFS_IP(dip)->commit_sem);
- up(&JFS_IP(ip)->commit_sem);
+ mutex_unlock(&JFS_IP(ip)->commit_mutex);
+ mutex_unlock(&JFS_IP(dip)->commit_mutex);
if (rc) {
+ free_ea_wmap(ip);
ip->i_nlink = 0;
iput(ip);
} else
out2:
free_UCSname(&dname);
-#ifdef CONFIG_JFS_POSIX_ACL
- if (rc == 0)
- jfs_init_acl(ip, dip);
-#endif
-
out1:
jfs_info("jfs_symlink: rc:%d", rc);
return rc;
*/
tid = txBegin(new_dir->i_sb, 0);
- down(&JFS_IP(new_dir)->commit_sem);
- down(&JFS_IP(old_ip)->commit_sem);
+ mutex_lock(&JFS_IP(new_dir)->commit_mutex);
+ mutex_lock(&JFS_IP(old_ip)->commit_mutex);
if (old_dir != new_dir)
- down(&JFS_IP(old_dir)->commit_sem);
+ mutex_lock(&JFS_IP(old_dir)->commit_mutex);
if (new_ip) {
- down(&JFS_IP(new_ip)->commit_sem);
+ mutex_lock(&JFS_IP(new_ip)->commit_mutex);
/*
* Change existing directory entry to new inode number
*/
old_ip->i_ino, JFS_RENAME);
if (rc)
goto out4;
- new_ip->i_nlink--;
+ drop_nlink(new_ip);
if (S_ISDIR(new_ip->i_mode)) {
- new_ip->i_nlink--;
+ drop_nlink(new_ip);
if (new_ip->i_nlink) {
- up(&JFS_IP(new_dir)->commit_sem);
- up(&JFS_IP(old_ip)->commit_sem);
+ mutex_unlock(&JFS_IP(new_ip)->commit_mutex);
if (old_dir != new_dir)
- up(&JFS_IP(old_dir)->commit_sem);
+ mutex_unlock(&JFS_IP(old_dir)->commit_mutex);
+ mutex_unlock(&JFS_IP(old_ip)->commit_mutex);
+ mutex_unlock(&JFS_IP(new_dir)->commit_mutex);
if (!S_ISDIR(old_ip->i_mode) && new_ip)
IWRITE_UNLOCK(new_ip);
jfs_error(new_ip->i_sb,
/* free block resources */
if ((new_size = commitZeroLink(tid, new_ip)) < 0) {
txAbort(tid, 1); /* Marks FS Dirty */
- rc = new_size;
+ rc = new_size;
goto out4;
}
tblk = tid_to_tblock(tid);
goto out4;
}
if (S_ISDIR(old_ip->i_mode))
- new_dir->i_nlink++;
+ inc_nlink(new_dir);
}
/*
* Remove old directory entry
goto out4;
}
if (S_ISDIR(old_ip->i_mode)) {
- old_dir->i_nlink--;
+ drop_nlink(old_dir);
if (old_dir != new_dir) {
/*
* Change inode number of parent for moved directory
out4:
txEnd(tid);
-
- up(&JFS_IP(new_dir)->commit_sem);
- up(&JFS_IP(old_ip)->commit_sem);
- if (old_dir != new_dir)
- up(&JFS_IP(old_dir)->commit_sem);
if (new_ip)
- up(&JFS_IP(new_ip)->commit_sem);
+ mutex_unlock(&JFS_IP(new_ip)->commit_mutex);
+ if (old_dir != new_dir)
+ mutex_unlock(&JFS_IP(old_dir)->commit_mutex);
+ mutex_unlock(&JFS_IP(old_ip)->commit_mutex);
+ mutex_unlock(&JFS_IP(new_dir)->commit_mutex);
while (new_size && (rc == 0)) {
tid = txBegin(new_ip->i_sb, 0);
- down(&JFS_IP(new_ip)->commit_sem);
+ mutex_lock(&JFS_IP(new_ip)->commit_mutex);
new_size = xtTruncate_pmap(tid, new_ip, new_size);
if (new_size < 0) {
txAbort(tid, 1);
- rc = new_size;
+ rc = new_size;
} else
rc = txCommit(tid, 1, &new_ip, COMMIT_SYNC);
txEnd(tid);
- up(&JFS_IP(new_ip)->commit_sem);
+ mutex_unlock(&JFS_IP(new_ip)->commit_mutex);
}
if (new_ip && (new_ip->i_nlink == 0))
set_cflag(COMMIT_Nolink, new_ip);
goto out;
ip = ialloc(dir, mode);
- if (ip == NULL) {
- rc = -ENOSPC;
+ if (IS_ERR(ip)) {
+ rc = PTR_ERR(ip);
goto out1;
}
jfs_ip = JFS_IP(ip);
tid = txBegin(dir->i_sb, 0);
- down(&JFS_IP(dir)->commit_sem);
- down(&JFS_IP(ip)->commit_sem);
+ mutex_lock(&JFS_IP(dir)->commit_mutex);
+ mutex_lock(&JFS_IP(ip)->commit_mutex);
- if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE)))
+ rc = jfs_init_acl(tid, ip, dir);
+ if (rc)
+ goto out3;
+
+ rc = jfs_init_security(tid, ip, dir);
+ if (rc) {
+ txAbort(tid, 0);
+ goto out3;
+ }
+
+ if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE))) {
+ txAbort(tid, 0);
goto out3;
+ }
tblk = tid_to_tblock(tid);
tblk->xflag |= COMMIT_CREATE;
tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
ino = ip->i_ino;
- if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack)))
+ if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack))) {
+ txAbort(tid, 0);
goto out3;
+ }
ip->i_op = &jfs_file_inode_operations;
jfs_ip->dev = new_encode_dev(rdev);
out3:
txEnd(tid);
- up(&JFS_IP(ip)->commit_sem);
- up(&JFS_IP(dir)->commit_sem);
+ mutex_unlock(&JFS_IP(ip)->commit_mutex);
+ mutex_unlock(&JFS_IP(dir)->commit_mutex);
if (rc) {
+ free_ea_wmap(ip);
ip->i_nlink = 0;
iput(ip);
} else
out1:
free_UCSname(&dname);
-#ifdef CONFIG_JFS_POSIX_ACL
- if (rc == 0)
- jfs_init_acl(ip, dir);
-#endif
-
out:
jfs_info("jfs_mknod: returning %d", rc);
return rc;
jfs_info("jfs_lookup: name = %s", name);
+ if (JFS_SBI(dip->i_sb)->mntflag & JFS_OS2)
+ dentry->d_op = &jfs_ci_dentry_operations;
if ((name[0] == '.') && (len == 1))
inum = dip->i_ino;
return ERR_PTR(-EACCES);
}
- if (JFS_SBI(dip->i_sb)->mntflag & JFS_OS2)
- dentry->d_op = &jfs_ci_dentry_operations;
-
+ dx_propagate_tag(nd, ip);
dentry = d_splice_alias(ip, dentry);
if (dentry && (JFS_SBI(dip->i_sb)->mntflag & JFS_OS2))
.setattr = jfs_setattr,
.permission = jfs_permission,
#endif
+ .sync_flags = jfs_sync_flags,
};
-struct file_operations jfs_dir_operations = {
+const struct file_operations jfs_dir_operations = {
.read = generic_read_dir,
.readdir = jfs_readdir,
.fsync = jfs_fsync,
+ .ioctl = jfs_ioctl,
};
static int jfs_ci_hash(struct dentry *dir, struct qstr *this)