root/branches/Orange-Branch/src/kernel/linux-2.6/inode.c @ 8872

Revision 8872, 19.4 KB (checked in by mtmoore, 2 years ago)

compiler warning cleanup

Line 
1/*
2 * (C) 2001 Clemson University and The University of Chicago
3 *
4 * See COPYING in top-level directory.
5 */
6
7/** \file
8 *  \ingroup pvfs2linux
9 *
10 *  Linux VFS inode operations.
11 */
12
13#include "pvfs2-kernel.h"
14#include "pvfs2-bufmap.h"
15#include "pvfs2-types.h"
16#include "pvfs2-internal.h"
17
18static int read_one_page(struct page *page)
19{
20    void *page_data;
21    int ret, max_block;
22    ssize_t bytes_read = 0;
23    struct inode *inode = page->mapping->host;
24    const uint32_t blocksize = PAGE_CACHE_SIZE;  /* inode->i_blksize */
25    const uint32_t blockbits = PAGE_CACHE_SHIFT; /* inode->i_blkbits */
26
27    gossip_debug(GOSSIP_INODE_DEBUG, "pvfs2_readpage called with page %p\n",page);
28    page_data = pvfs2_kmap(page);
29
30    max_block = ((inode->i_size / blocksize) + 1);
31
32    if (page->index < max_block)
33    {
34        loff_t blockptr_offset =
35            (((loff_t)page->index) << blockbits);
36        bytes_read = pvfs2_inode_read(
37            inode, page_data, blocksize, &blockptr_offset, 0, inode->i_size);
38    }
39    /* only zero remaining unread portions of the page data */
40    if (bytes_read > 0)
41    {
42        memset(page_data + bytes_read, 0, blocksize - bytes_read);
43    }
44    else
45    {
46        memset(page_data, 0, blocksize);
47    }
48    /* takes care of potential aliasing */
49    flush_dcache_page(page);
50    if (bytes_read < 0)
51    {
52        ret = bytes_read;
53        SetPageError(page);
54    }
55    else
56    {
57        SetPageUptodate(page);
58        if (PageError(page))
59        {
60            ClearPageError(page);
61        }
62        ret = 0;
63    }
64    pvfs2_kunmap(page);
65    /* unlock the page after the ->readpage() routine completes */
66    unlock_page(page);
67    return ret;
68}
69
70static int pvfs2_readpage(
71    struct file *file,
72    struct page *page)
73{
74    return read_one_page(page);
75}
76
77#ifndef PVFS2_LINUX_KERNEL_2_4
78static int pvfs2_readpages(
79    struct file *file,
80    struct address_space *mapping,
81    struct list_head *pages,
82    unsigned nr_pages)
83{
84    int page_idx;
85    int ret;
86
87    gossip_debug(GOSSIP_INODE_DEBUG, "pvfs2_readpages called\n");
88
89    for (page_idx = 0; page_idx < nr_pages; page_idx++)
90    {
91        struct page *page;
92        page = list_entry(pages->prev, struct page, lru);
93        list_del(&page->lru);
94        if (!add_to_page_cache(page, mapping, page->index, GFP_KERNEL)) {
95            ret = read_one_page(page);
96            gossip_debug(GOSSIP_INODE_DEBUG, "failure adding page to cache, "
97                         "read_one_page returned: %d\n", ret);
98        }
99        else {
100            page_cache_release(page);
101        }
102    }
103    BUG_ON(!list_empty(pages));
104    return 0;
105}
106
107#ifdef HAVE_INT_RETURN_ADDRESS_SPACE_OPERATIONS_INVALIDATEPAGE
108static int pvfs2_invalidatepage(struct page *page, unsigned long offset)
109#else
110static void pvfs2_invalidatepage(struct page *page, unsigned long offset)
111#endif
112{
113    gossip_debug(GOSSIP_INODE_DEBUG, "pvfs2_invalidatepage called on page %p "
114                "(offset is %lu)\n", page, offset);
115
116    ClearPageUptodate(page);
117    ClearPageMappedToDisk(page);
118#ifdef HAVE_INT_RETURN_ADDRESS_SPACE_OPERATIONS_INVALIDATEPAGE
119    return 0;
120#else
121    return;
122#endif
123
124}
125
126#ifdef HAVE_INT_ARG2_ADDRESS_SPACE_OPERATIONS_RELEASEPAGE
127static int pvfs2_releasepage(struct page *page, int foo)
128#else
129static int pvfs2_releasepage(struct page *page, gfp_t foo)
130#endif
131{
132    gossip_debug(GOSSIP_INODE_DEBUG, "pvfs2_releasepage called on page %p\n", page);
133    return 0;
134}
135
136struct backing_dev_info pvfs2_backing_dev_info =
137{
138#ifdef HAVE_BACKING_DEV_INFO_NAME
139    .name = "pvfs2",
140#endif
141    .ra_pages = 0,
142#ifdef HAVE_BDI_MEMORY_BACKED
143    /* old interface, up through 2.6.11 */
144    .memory_backed = 1 /* does not contribute to dirty memory */
145#else
146    .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
147#endif
148};
149#endif /* !PVFS2_LINUX_KERNEL_2_4 */
150
151/** PVFS2 implementation of address space operations */
152struct address_space_operations pvfs2_address_operations =
153{
154#ifdef PVFS2_LINUX_KERNEL_2_4
155    readpage : pvfs2_readpage
156#else
157    .readpage = pvfs2_readpage,
158    .readpages = pvfs2_readpages,
159    .invalidatepage = pvfs2_invalidatepage,
160    .releasepage = pvfs2_releasepage
161#endif
162};
163
164/** Change size of an object referenced by inode
165 */
166void pvfs2_truncate(struct inode *inode)
167{
168    loff_t orig_size = pvfs2_i_size_read(inode);
169
170    if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
171        return;
172    gossip_debug(GOSSIP_INODE_DEBUG, "pvfs2: pvfs2_truncate called on inode %llu "
173                "with size %ld\n", llu(get_handle_from_ino(inode)), (long) orig_size);
174
175    /* successful truncate when size changes also requires mtime updates
176     * although the mtime updates are propagated lazily!
177     */
178    if (pvfs2_truncate_inode(inode, inode->i_size) == 0
179            && (orig_size != pvfs2_i_size_read(inode)))
180    {
181        pvfs2_inode_t *pvfs2_inode = PVFS2_I(inode);
182        SetMtimeFlag(pvfs2_inode);
183        inode->i_mtime = CURRENT_TIME;
184        mark_inode_dirty_sync(inode);
185    }
186}
187
188/** Change attributes of an object referenced by dentry.
189 */
190int pvfs2_setattr(struct dentry *dentry, struct iattr *iattr)
191{
192    int ret = -EINVAL;
193    struct inode *inode = dentry->d_inode;
194
195    gossip_debug(GOSSIP_INODE_DEBUG, "pvfs2_setattr: called on %s\n",
196                 dentry->d_name.name);
197
198    ret = inode_change_ok(inode, iattr);
199    if (ret == 0)
200    {
201
202#ifdef HAVE_INODE_SETATTR
203        ret = inode_setattr(inode, iattr);
204#else
205        if ((iattr->ia_valid & ATTR_SIZE) &&
206           iattr->ia_size != i_size_read(inode))
207        {
208            ret = vmtruncate(inode, iattr->ia_size);
209            if (ret)
210                return ret;
211        }
212
213        setattr_copy(inode, iattr);
214        mark_inode_dirty(inode);
215        ret = 0;
216#endif /* HAVE_INODE_SETATTR */
217   
218        gossip_debug(GOSSIP_INODE_DEBUG, "pvfs2_setattr: inode_setattr returned %d\n", ret);
219
220        if (ret == 0)
221        {
222            ret = pvfs2_inode_setattr(inode, iattr);
223#if !defined(PVFS2_LINUX_KERNEL_2_4) && defined(HAVE_GENERIC_GETXATTR) && defined(CONFIG_FS_POSIX_ACL)
224            if (!ret && (iattr->ia_valid & ATTR_MODE))
225            {
226                /* change mod on a file that has ACLs */
227                ret = pvfs2_acl_chmod(inode);
228            }
229#endif
230        }
231    }
232    gossip_debug(GOSSIP_INODE_DEBUG, "pvfs2_setattr: returning %d\n", ret);
233    return ret;
234}
235
236#ifdef PVFS2_LINUX_KERNEL_2_4
237/** Linux 2.4 only equivalent of getattr
238 */
239int pvfs2_revalidate(struct dentry *dentry)
240{
241    int ret = 0;
242    struct inode *inode = (dentry ? dentry->d_inode : NULL);
243
244    gossip_debug(GOSSIP_INODE_DEBUG, "pvfs2_revalidate: called on %s\n", dentry->d_name.name);
245
246    /*
247     * A revalidate expects that all fields of the inode would be refreshed
248     * So we have no choice but to refresh all attributes.
249     */
250    ret = pvfs2_inode_getattr(inode, PVFS_ATTR_SYS_ALL_NOHINT);
251    if (ret)
252    {
253        /* assume an I/O error and flag inode as bad */
254        gossip_debug(GOSSIP_INODE_DEBUG, "%s:%s:%d calling make bad inode\n", __FILE__,  __func__, __LINE__);
255        pvfs2_make_bad_inode(inode);
256    }
257    return ret;
258}
259#else
260/** Obtain attributes of an object given a dentry
261 */
262int pvfs2_getattr(
263    struct vfsmount *mnt,
264    struct dentry *dentry,
265    struct kstat *kstat)
266{
267    int ret = -ENOENT;
268    struct inode *inode = dentry->d_inode;
269    pvfs2_inode_t *pvfs2_inode = NULL;
270
271    gossip_debug(GOSSIP_INODE_DEBUG,
272        "pvfs2_getattr: called on %s\n", dentry->d_name.name);
273
274    /* This seems to be the only place to reliably detect mount options
275     * parsed by the VFS layer.  Propigate them to our internal sb structure so
276     * that we can handle lazy time updates properly.
277     */
278#ifdef HAVE_MNT_NOATIME
279    if(mnt->mnt_flags && MNT_NOATIME)
280    {
281        inode->i_sb->s_flags |= MS_NOATIME;
282    }
283#endif
284#ifdef HAVE_MNT_NODIRATIME
285    if(mnt->mnt_flags && MNT_NODIRATIME)
286    {
287        inode->i_sb->s_flags |= MS_NODIRATIME;
288    }
289#endif
290
291    /*
292     * Similar to the above comment, a getattr also expects that all fields/attributes
293     * of the inode would be refreshed. So again, we dont have too much of a choice
294     * but refresh all the attributes.
295     */
296    ret = pvfs2_inode_getattr(inode, PVFS_ATTR_SYS_ALL_NOHINT);
297    if (ret == 0)
298    {
299        generic_fillattr(inode, kstat);
300        /* override block size reported to stat */
301        pvfs2_inode = PVFS2_I(inode);
302        kstat->blksize = pvfs2_inode->blksize;
303    }
304    else
305    {
306        /* assume an I/O error and flag inode as bad */
307        gossip_debug(GOSSIP_INODE_DEBUG, "%s:%s:%d calling make bad inode\n", __FILE__,  __func__, __LINE__);
308        pvfs2_make_bad_inode(inode);
309    }
310    return ret;
311}
312
313#ifdef HAVE_GETATTR_LITE_INODE_OPERATIONS
314
315uint32_t convert_to_pvfs2_mask(unsigned long lite_mask)
316{
317    uint32_t mask = 0;
318
319    if (SLITE_SIZET(lite_mask))
320        mask |= PVFS_ATTR_SYS_SIZE;
321    if (SLITE_ATIME(lite_mask))
322        mask |= PVFS_ATTR_SYS_ATIME;
323    if (SLITE_MTIME(lite_mask))
324        mask |= PVFS_ATTR_SYS_MTIME;
325    if (SLITE_CTIME(lite_mask))
326        mask |= PVFS_ATTR_SYS_CTIME;
327    return mask;
328}
329
330int pvfs2_getattr_lite(
331    struct vfsmount *mnt,
332    struct dentry *dentry,
333    struct kstat_lite *kstat_lite)
334{
335    int ret = -ENOENT;
336    struct inode *inode = dentry->d_inode;
337    uint32_t mask;
338
339    gossip_debug(GOSSIP_INODE_DEBUG, "pvfs2_getattr_lite: called on %s\n", dentry->d_name.name);
340
341    /*
342     * ->getattr_lite needs to refresh only certain fields
343     * of the inode and that is indicated by the lite_mask
344     * field of kstat_lite structure.
345     */
346    mask = convert_to_pvfs2_mask(kstat_lite->lite_mask);
347    ret = pvfs2_inode_getattr(inode, mask);
348    if (ret == 0)
349    {
350        generic_fillattr_lite(inode, kstat_lite);
351    }
352    else
353    {
354        /* assume an I/O error and flag inode as bad */
355        gossip_debug(GOSSIP_INODE_DEBUG, "%s:%s:%d calling make bad inode\n", __FILE__,  __func__, __LINE__);
356        pvfs2_make_bad_inode(inode);
357    }
358    return ret;
359}
360#endif
361#endif /* PVFS2_LINUX_KERNEL_2_4 */
362
363/** PVFS2 implementation of VFS inode operations for files */
364struct inode_operations pvfs2_file_inode_operations =
365{
366#ifdef PVFS2_LINUX_KERNEL_2_4
367    truncate : pvfs2_truncate,
368    setattr : pvfs2_setattr,
369    revalidate : pvfs2_revalidate,
370#ifdef HAVE_XATTR
371    setxattr : pvfs2_setxattr,
372    getxattr : pvfs2_getxattr,
373    removexattr: pvfs2_removexattr,
374    listxattr: pvfs2_listxattr,
375#endif
376#else
377    .truncate = pvfs2_truncate,
378    .setattr = pvfs2_setattr,
379    .getattr = pvfs2_getattr,
380#ifdef HAVE_GETATTR_LITE_INODE_OPERATIONS
381    .getattr_lite = pvfs2_getattr_lite,
382#endif
383#if defined(HAVE_GENERIC_GETXATTR) && defined(CONFIG_FS_POSIX_ACL)
384    .setxattr = generic_setxattr,
385    .getxattr = generic_getxattr,
386    .removexattr = generic_removexattr,
387#else
388    .setxattr = pvfs2_setxattr,
389    .getxattr = pvfs2_getxattr,
390    .removexattr = pvfs2_removexattr,
391#endif
392    .listxattr = pvfs2_listxattr,
393#if defined(HAVE_GENERIC_GETXATTR) && defined(CONFIG_FS_POSIX_ACL)
394    .permission = pvfs2_permission,
395#endif
396#ifdef HAVE_FILL_HANDLE_INODE_OPERATIONS
397    .fill_handle = pvfs2_fill_handle,
398#endif
399#endif
400};
401
402#if defined(HAVE_IGET5_LOCKED) || defined (HAVE_IGET4_LOCKED)
403
404/*
405 * Given a PVFS2 object identifier (fsid, handle), convert it into a ino_t type
406 * that will be used as a hash-index from where the handle will
407 * be searched for in the VFS hash table of inodes.
408 */
409static inline ino_t pvfs2_handle_hash(PVFS_object_ref *ref)
410{
411    if (!ref)
412        return 0;
413    return pvfs2_handle_to_ino(ref->handle);
414}
415
416/* the ->set callback of iget5_locked and friends. Sorta equivalent to the ->read_inode()
417 * callback if we are using iget and friends
418 */
419int pvfs2_set_inode(struct inode *inode, void *data)
420{
421    /* callbacks to set inode number handle */
422    PVFS_object_ref *ref = (PVFS_object_ref *) data;
423    pvfs2_inode_t *pvfs2_inode = NULL;
424
425    /* Make sure that we have sane parameters */
426    if (!data || !inode)
427        return 0;
428    pvfs2_inode = PVFS2_I(inode);
429    if (!pvfs2_inode)
430        return 0;
431    pvfs2_inode_initialize(pvfs2_inode);
432    pvfs2_inode->refn.fs_id  = ref->fs_id;
433    pvfs2_inode->refn.handle = ref->handle;
434    return 0;
435}
436
437#ifdef HAVE_IGET5_LOCKED
438static int
439pvfs2_test_inode(struct inode *inode, void *data)
440#elif defined(HAVE_IGET4_LOCKED)
441static int
442pvfs2_test_inode(struct inode *inode, unsigned long ino, void *data)
443#endif
444{
445    /* callbacks to determine if handles match */
446    PVFS_object_ref *ref = (PVFS_object_ref *) data;
447    pvfs2_inode_t *pvfs2_inode = NULL;
448
449    pvfs2_inode = PVFS2_I(inode);
450    return (pvfs2_inode->refn.handle == ref->handle && pvfs2_inode->refn.fs_id == ref->fs_id);
451}
452#endif
453
454/*
455 * Front-end to lookup the inode-cache maintained by the VFS using the PVFS2
456 * file handle instead of the inode number.
457 * Problem with iget() is well-documented in that it can lead to possible
458 * collissions especially for a file-system with 64 bit handles since inode->i_ino
459 * is only a scalar field (32 bits). So the trick now is to use iget4_locked (OR) iget5_locked
460 * if the kernel defines one and set inode number to be just a hash for the
461 * handle
462 * @sb: the file system super block instance
463 * @ref: The PVFS2 object for which we are trying to locate an inode structure
464 * @keep_locked : indicates whether the inode must be simply allocated and not filled
465 * in with the results from a ->getattr. i.e. if keep_locked is set to 0, we do a getattr() and
466 * unlock the inode and if set to 1, we do not issue a getattr() and keep it locked
467 *
468 * Boy, this function is so ugly with all these macros. I wish I could find a better
469 * way to reduce the macro clutter.
470 */
471struct inode *pvfs2_iget_common(struct super_block *sb, PVFS_object_ref *ref, int keep_locked)
472{
473    struct inode *inode = NULL;
474    unsigned long hash;
475
476#if defined(HAVE_IGET5_LOCKED) || defined(HAVE_IGET4_LOCKED)
477    hash = pvfs2_handle_hash(ref);
478#if defined(HAVE_IGET5_LOCKED)
479    inode = iget5_locked(sb, hash, pvfs2_test_inode, pvfs2_set_inode, ref);
480#elif defined(HAVE_IGET4_LOCKED)
481    inode = iget4_locked(sb, hash, pvfs2_test_inode, ref);
482#endif
483#else
484    hash = (unsigned long) ref->handle;
485#ifdef HAVE_IGET_LOCKED
486    inode = iget_locked(sb, hash);
487#else
488    /* iget() internally issues a call to read_inode() */
489    inode = iget(sb, hash);
490#endif
491#endif
492    if (!keep_locked)
493    {
494#if defined(HAVE_IGET5_LOCKED) || defined(HAVE_IGET4_LOCKED) || defined(HAVE_IGET_LOCKED)
495        if (inode && (inode->i_state & I_NEW))
496        {
497            inode->i_ino = hash; /* needed for stat etc */
498            /* iget4_locked and iget_locked dont invoke the set_inode callback.
499             * So we work around that by stashing the pvfs object reference
500             * in the inode specific private part for 2.4 kernels and invoking
501             * the setcallback explicitly for 2.6 kernels.
502             */
503#if defined(HAVE_IGET4_LOCKED) || defined(HAVE_IGET_LOCKED)
504            if (PVFS2_I(inode)) {
505                pvfs2_set_inode(inode, ref);
506            }
507            else {
508#ifdef PVFS2_LINUX_KERNEL_2_4
509                inode->u.generic_ip = (void *) ref;
510#endif
511            }
512#endif
513            /* issue a call to read the inode */
514            pvfs2_read_inode(inode);
515            unlock_new_inode(inode);
516        }
517#endif
518    }
519    gossip_debug(GOSSIP_INODE_DEBUG, "iget handle %llu, fsid %d hash %ld i_ino %lu\n",
520                 ref->handle, ref->fs_id, hash, inode->i_ino);
521    return inode;
522}
523
524/** Allocates a Linux inode structure with additional PVFS2-specific
525 *  private data (I think -- RobR).
526 */
527struct inode *pvfs2_get_custom_inode_common(
528    struct super_block *sb,
529    struct inode *dir,
530    int mode,
531    dev_t dev,
532    PVFS_object_ref object,
533    int from_create)
534{
535    struct inode *inode = NULL;
536    pvfs2_inode_t *pvfs2_inode = NULL;
537
538    gossip_debug(GOSSIP_INODE_DEBUG, "pvfs2_get_custom_inode_common: called\n  (sb is %p | "
539                "MAJOR(dev)=%u | MINOR(dev)=%u)\n", sb, MAJOR(dev),
540                MINOR(dev));
541
542    inode = pvfs2_iget(sb, &object);
543    if (inode)
544    {
545        /* initialize pvfs2 specific private data */
546        pvfs2_inode = PVFS2_I(inode);
547        if (!pvfs2_inode)
548        {
549            iput(inode);
550            gossip_err("pvfs2_get_custom_inode: PRIVATE "
551                        "DATA NOT ALLOCATED\n");
552            return NULL;
553        }
554
555        /*
556         * Since we are using the same function to create a new on-disk object
557         * as well as to create an in-memory object, the mode of the object
558         * needs to be set carefully. If we are called from a function that is
559         * creating a new on-disk object, set its mode here since the caller is
560         * providing it. Else let it be since the getattr should fill it up
561         * properly.
562         */
563        if (from_create)
564        {
565            /* the exception is when we are creating a directory that needs
566             * to inherit the setgid bit.  That much we need to preserve from
567             * the getattr's view of the mode.
568             */
569            if(inode->i_mode & S_ISGID)
570            {
571                gossip_debug(GOSSIP_INODE_DEBUG,
572                    "pvfs2_get_custom_inode_commmon: setting SGID bit.\n");
573                inode->i_mode = mode | S_ISGID;
574            }
575            else
576            {
577                inode->i_mode = mode;
578            }
579        }
580        gossip_debug(GOSSIP_INODE_DEBUG,
581                "pvfs2_get_custom_inode_common: inode: %p, inode->i_mode %o\n",
582                inode, inode->i_mode);
583        inode->i_mapping->host = inode;
584#ifdef HAVE_CURRENT_FSUID
585        inode->i_uid = current_fsuid();
586        inode->i_gid = current_fsgid();
587#else
588        inode->i_uid = current->fsuid;
589        inode->i_gid = current->fsgid;
590#endif
591        inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
592        inode->i_size = PAGE_CACHE_SIZE;
593#ifdef HAVE_I_BLKSIZE_IN_STRUCT_INODE
594        inode->i_blksize = PAGE_CACHE_SIZE;
595#endif
596        inode->i_blkbits = PAGE_CACHE_SHIFT;
597        inode->i_blocks = 0;
598        inode->i_rdev = dev;
599        inode->i_bdev = NULL;
600        inode->i_cdev = NULL;
601        inode->i_mapping->a_ops = &pvfs2_address_operations;
602#ifndef PVFS2_LINUX_KERNEL_2_4
603        inode->i_mapping->backing_dev_info = &pvfs2_backing_dev_info;
604#endif
605
606        gossip_debug(GOSSIP_INODE_DEBUG, "pvfs2_get_custom_inode: inode %p allocated\n  "
607                    "(pvfs2_inode is %p | sb is %p)\n", inode,
608                    pvfs2_inode, inode->i_sb);
609
610        if ((mode & S_IFMT) == S_IFREG)
611        {
612            inode->i_op = &pvfs2_file_inode_operations;
613            inode->i_fop = &pvfs2_file_operations;
614
615#ifdef HAVE_I_BLKSIZE_IN_STRUCT_INODE
616            inode->i_blksize = pvfs_bufmap_size_query();
617#endif
618            inode->i_blkbits = PAGE_CACHE_SHIFT;
619        }
620        else if ((mode & S_IFMT) == S_IFLNK)
621        {
622            inode->i_op = &pvfs2_symlink_inode_operations;
623            inode->i_fop = NULL;
624        }
625        else if ((mode & S_IFMT) == S_IFDIR)
626        {
627            inode->i_op = &pvfs2_dir_inode_operations;
628            inode->i_fop = &pvfs2_dir_operations;
629
630            /* dir inodes start with i_nlink == 2 (for "." entry) */
631            inode->i_nlink++;
632        }
633        else
634        {
635            gossip_debug(GOSSIP_INODE_DEBUG, "pvfs2_get_custom_inode: unsupported mode\n");
636            goto error;
637        }
638#if !defined(PVFS2_LINUX_KERNEL_2_4) && defined(HAVE_GENERIC_GETXATTR) && defined(CONFIG_FS_POSIX_ACL)
639        gossip_debug(GOSSIP_ACL_DEBUG, "Initializing ACL's for inode %llu\n",
640                llu(get_handle_from_ino(inode)));
641        /* Initialize the ACLs of the new inode */
642        pvfs2_init_acl(inode, dir);
643#endif
644    }
645error:
646    return inode;
647}
648
649/*
650 * Local variables:
651 *  c-indent-level: 4
652 *  c-basic-offset: 4
653 * End:
654 *
655 * vim: ts=8 sts=4 sw=4 expandtab
656 */
Note: See TracBrowser for help on using the browser.